Распаковка libjpeg в RAW не работает

Я использую 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

person Matthew Hoggan    schedule 01.12.2011    source источник


Ответы (1)


size_t count = размер / размер (беззнаковый символ *);

вы получаете только 1/4 записанных необработанных данных (фактически, в 64-битном режиме только 1/8). количество должно быть таким же, как размер (подсчет символов, а не указателей)

person blabla999    schedule 12.12.2011