Reputation: 43
I have a Fujifilm X-T10 that produces RAF files and I would like to produce a progressive JPEG from a RAF.
If I use this command:
dcraw -v -o 0 -c DSCF7257.RAF | cjpeg -quality 92 -progressive > DSCF7257.JPG
I can successfully create a progressive JPEG.
I tried to write a program that does the exact same thing but simpler but it does not work because it returns Empty JPEG image (DNL not supported)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <libraw/libraw.h>
#include <jpeglib.h>
int main(int argc, char **argv)
{
if (argc != 2) {
fprintf(stderr, "usage: %s <filename>.RAF\n", argv[0]);
exit(EXIT_FAILURE);
}
char *src_name = argv[1];
char *src_name_2 = strdup(src_name);
const char *delim = "/";
char *tok = NULL;
char *dst_name = NULL;
tok = strtok(src_name_2, delim);
while ((tok = strtok(NULL, delim)) != NULL)
dst_name = tok;
dst_name = strcat(strtok(dst_name, "."), ".JPG");
FILE *src_file = fopen(src_name, "rb");
fseek(src_file, 0, SEEK_END);
long src_len = ftell(src_file);
fseek(src_file, 0, SEEK_SET);
size_t chunk = 1000 * 1000 * 5;
size_t nmembs = src_len / chunk;
uint8_t *raw_buf = (uint8_t *) malloc(src_len * sizeof(uint8_t));
fread(raw_buf, chunk, nmembs, src_file);
libraw_data_t *raw_dec = libraw_init(0);
libraw_open_buffer(raw_dec, raw_buf, sizeof(*raw_buf));
libraw_unpack(raw_dec);
libraw_dcraw_process(raw_dec);
libraw_processed_image_t *raw_img = libraw_dcraw_make_mem_image(raw_dec, NULL);
struct jpeg_compress_struct jpeg_enc;
struct jpeg_error_mgr jpeg_err;
JSAMPROW row_pointer[1];
int row_stride;
jpeg_enc.err = jpeg_std_error(&jpeg_err);
jpeg_create_compress(&jpeg_enc);
FILE *dst_file = fopen(dst_name, "wb");
jpeg_stdio_dest(&jpeg_enc, dst_file);
jpeg_enc.image_width = raw_img->width;
jpeg_enc.image_height = raw_img->height;
jpeg_enc.input_components = 3;
jpeg_set_defaults(&jpeg_enc);
jpeg_set_colorspace(&jpeg_enc, JCS_YCbCr);
jpeg_set_quality(&jpeg_enc, 92, FALSE);
jpeg_simple_progression(&jpeg_enc);
jpeg_start_compress(&jpeg_enc, FALSE);
row_stride = jpeg_enc.image_width * jpeg_enc.input_components;
while (jpeg_enc.next_scanline < jpeg_enc.image_height) {
row_pointer[0] = &raw_img->data[jpeg_enc.next_scanline * row_stride];
jpeg_write_scanlines(&jpeg_enc, row_pointer, 1);
}
jpeg_finish_compress(&jpeg_enc);
jpeg_destroy_compress(&jpeg_enc);
fclose(src_file);
fclose(dst_file);
free(raw_buf);
free(src_name_2);
libraw_dcraw_clear_mem(raw_img);
libraw_recycle(raw_dec);
libraw_close(raw_dec);
exit(EXIT_SUCCESS);
}
Suggestions ?
Gianluca
Upvotes: 2
Views: 80
Reputation: 43
Here the revised code that works although still lacks of proper error handling:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <libraw/libraw.h>
#include <jpeglib.h>
int main(int argc, char **argv)
{
if (argc != 3) {
fprintf(stderr, "usage: %s <filename>.RAF <filename>.JPG\n", argv[0]);
exit(EXIT_FAILURE);
}
char *src_name = argv[1];
char *dst_name = argv[2];
FILE *src_file = fopen(src_name, "rb");
libraw_data_t *raw_dec = libraw_init(0);
libraw_open_file(raw_dec, src_name);
libraw_unpack(raw_dec);
libraw_dcraw_process(raw_dec);
libraw_processed_image_t *raw_img = libraw_dcraw_make_mem_image(raw_dec, NULL);
struct jpeg_compress_struct jpeg_enc;
struct jpeg_error_mgr jpeg_err;
jpeg_enc.err = jpeg_std_error(&jpeg_err);
jpeg_create_compress(&jpeg_enc);
FILE *dst_file = fopen(dst_name, "wb");
jpeg_stdio_dest(&jpeg_enc, dst_file);
jpeg_enc.image_width = raw_img->width;
jpeg_enc.image_height = raw_img->height;
jpeg_enc.input_components = 3;
jpeg_enc.in_color_space = JCS_RGB;
jpeg_set_defaults(&jpeg_enc);
jpeg_set_quality(&jpeg_enc, 92, TRUE);
jpeg_simple_progression(&jpeg_enc);
jpeg_start_compress(&jpeg_enc, TRUE);
JSAMPROW row_pointer[1];
uint8_t *image = (uint8_t *) raw_img->data;
while (jpeg_enc.next_scanline < jpeg_enc.image_height) {
row_pointer[0] = &image[jpeg_enc.next_scanline * jpeg_enc.image_width * 3];
jpeg_write_scanlines(&jpeg_enc, row_pointer, 1);
}
jpeg_finish_compress(&jpeg_enc);
jpeg_destroy_compress(&jpeg_enc);
fclose(src_file);
fclose(dst_file);
libraw_dcraw_clear_mem(raw_img);
libraw_recycle(raw_dec);
libraw_close(raw_dec);
exit(EXIT_SUCCESS);
}
The problem in the previous code snippet was that I was using - wrongly - sizeof(*raw_buf)
to get the real size of the raw_buf
variable content.
I simplified the example by reading from a file.
Sincerely
Gianluca
Upvotes: 0