c - libjpeg 解压缩到 RAW 不工作

标签 c jpeg libjpeg file-conversion

我在 RHEL 6.0 x86_64 机器上使用以下版本的 libjpeg。

[mehoggan@hogganz400 jpeg_to_raw.c]$ rpm -qa libjpeg
libjpeg-6b-46.el6.x86_64

我有以下代码,它以一个 .jpeg 文件作为输入,并写出一个 .raw 文件。当我运行该程序时,文件的大小会扩大,这让我相信该程序正在运行:

[mehoggan@hogganz400 jpeg_to_raw.c]$ ls -l
total 600
-rwxrwxr-x 1 mehoggan mehoggan  10113 Dec  1 10:32 jpeg_to_raw
-rw-rw-r-- 1 mehoggan mehoggan   3311 Dec  1 10:32 jpeg_to_raw.c
-rw-rw-r-- 1 mehoggan mehoggan     75 Dec  1 10:27 Makefile
-rw-rw-r-- 1 mehoggan mehoggan 215205 Dec  1 09:19 test.jpg
-rw-rw-r-- 1 mehoggan mehoggan 374850 Dec  1 10:32 test_out.raw

然而,当我使用 Irfanview(和相关插件)打开文件时,只有一小部分图像打开。代码可以在下面找到:

#include <stdio.h>
#include <jpeglib.h>
#include <stdlib.h>
#include <unistd.h>

/* we will be using this uninitialized pointer later to store raw, uncompressd image */
unsigned char *raw_image = NULL;
unsigned int size;

/**
 * print the information for what was stored in the JPEG File
 **/
void print_jpeg_info(struct jpeg_decompress_struct cinfo)
{
    printf("JPEG File Information: \n");
    printf("Image width and height: %d pixels and %d pixels.\n", cinfo.image_width, cinfo.image_height);
    printf("Color components per pixel: %d.\n", cinfo.num_components);
    printf("Color space: %d.\n", cinfo.jpeg_color_space);
    printf("Raw flag is: %d.\n", cinfo.raw_data_out);
}

/**
 * read_jpeg_file Reads from a jpeg file on disk specified by filename and saves into the
 * raw_image buffer in an uncompressed format.
 *
 * \returns positive integer if successful, -1 otherwise
 * \param *filename char string specifying the file name to read from
 **/
int read_jpeg_file(char *filename)
{
    /* these are standard libjpeg structures for reading(decompression) */
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    /* libjpeg data structure for storing one row, that is, scanline of an image */
    JSAMPROW row_pointer[1];
    FILE *infile = fopen(filename, "rb");
    unsigned long location = 0;
    int i = 0;
    if (!infile) {
        printf("Error opening jpeg file %s\n!", filename);
        return -1;
    }
    /* here we set up the standard libjpeg error handler */
    cinfo.err = jpeg_std_error(&jerr);
    /* setup decompression process and source, then read JPEG header */
    jpeg_create_decompress(&cinfo);
    /* this makes the library read from infile */
    jpeg_stdio_src(&cinfo, infile);
    /* reading the image header which contains image information */
    jpeg_read_header(&cinfo, TRUE);
    print_jpeg_info(cinfo);
    jpeg_start_decompress(&cinfo);

    /* allocate memory to hold the uncompressed image */
    size = cinfo.output_width*cinfo.output_height*cinfo.num_components;
    raw_image = (unsigned char*)malloc(size);
    /* now actually read the jpeg into the raw buffer */
    row_pointer[0] = (unsigned char *)malloc(cinfo.output_width*cinfo.num_components);
    /* read one scan line at a time */
    while (cinfo.output_scanline < cinfo.image_height) {
        jpeg_read_scanlines( &cinfo, row_pointer, 1 );
        for (i=0; i<cinfo.image_width*cinfo.num_components;i++) {
            raw_image[location++] = row_pointer[0][i];
        }
    }
    /* wrap up decompression, destroy objects, free pointers and close open files */
    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
    free(row_pointer[0]);
    fclose(infile);
    /* yup, we succeeded! */
    return 1;
}

    int main(int argc, char *argv[])
    {
        char *infilename = "test.jpg";
        if (read_jpeg_file(infilename) > 0) {
            size_t count = size / sizeof(unsigned char*);
            fprintf(stdout, "The number of unsigned chars in raw_image = %d\n", (int)count);
            FILE *ofile = fopen("test_out.raw", "w+");
            ssize_t data_out = fwrite(raw_image, count, sizeof(unsigned char), ofile);
            fprintf(stdout, "%d", (int)data_out);
            fclose(ofile);
        }
        else 
            return -1;
        return 0;
    }

您如何看待程序没有写出所有数据的原因?或者为什么它可能会破坏数据?

用于构建这个简单应用程序的 makefile 是:

jpeg_to_raw : jpeg_to_raw.c
    gcc jpeg_to_raw.c -Wall -o jpeg_to_raw -ljpeg

最佳答案

size_t count = size/sizeof(unsigned char*);

只得到写入原始数据的 1/4(实际上,在 64 位模式下只有 1/8)。 计数应该与大小相同(计算字符,而不是指针)

关于c - libjpeg 解压缩到 RAW 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8346800/

相关文章:

c - 如何修复使用strtok后打印的乱码

opencv - 在二值化过程中防止JPEG压缩伪影

c - 在运行时找出 libjpeg 版本(或其他防止中止的方法)?

c - 错误的 JPEG 库版本 : library is 80, 调用者期望 62

c - 从 NTP 服务器(Cortex M3、Stellaris LM3S6965)获取时间

在 C 中通过引用正确地将 char 数组和 char 指针传递给函数

c - 使用回车反转字符串打印

c++ - 在 C++ 中从 HBITMAP 转换为 Jpeg 或 Png

r - 如何使用 r 将 tiff 图像转换为 jpeg

android - 在 NDK 构建中包含 libjpeg