libraw + mozjpeg:空 JPEG 图像(不支持 DNL)

问题描述 投票:0回答:1

我有一台可以生成 RAF 文件的 Fujifilm X-T10,我想从 RAF 生成渐进式 JPEG。

如果我使用这个命令:

dcraw -v -o 0 -c DSCF7257.RAF | cjpeg -quality 92 -progressive > DSCF7257.JPG

我可以成功创建渐进式 JPEG。

我尝试编写一个程序,执行完全相同的操作,但更简单,但它不起作用,因为它返回 空 JPEG 图像(不支持 DNL)

#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);
}

建议?

吉安卢卡

c c11 libjpeg libraw mozjpeg
1个回答
0
投票

这里修改后的代码可以工作,尽管仍然缺乏适当的错误处理:

#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);
}

前面的代码片段中的问题是我错误地使用了 -

sizeof(*raw_buf)
来获取
raw_buf
变量内容的实际大小。

我通过读取文件简化了示例。

真诚的

吉安卢卡

© www.soinside.com 2019 - 2024. All rights reserved.