libjpeg解压缩到RAW无法正常工作

时间:2011-12-01 19:00:34

标签: 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

1 个答案:

答案 0 :(得分:2)

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

只能获得原始数据的1/4(实际上,在64位模式下仅为1/8)。 count应该与size相同(计算字符,而不是指针)