I’m on Ubuntu Intrepid and I’m using jpeglib62 6b-14. I was working on some code, which only gave a black screen with some garbled output at the top when I tried to run it. After a few hours of debugging I got it down to pretty much the JPEG base, so I took the example code, wrote a little piece of code around it and the output was exactly the same.
I’m convinced jpeglib is used in a lot more places on this system and it’s simply the version from the repositories so I’m hesitant to say that this is a bug in jpeglib or the Ubuntu packaging.
I put the example code below (most comments stripped). The input JPEG file is an uncompressed 640×480 file with 3 channels, so it should be 921600 bytes (and it is). The output image is JFIF and around 9000 bytes.
If you could help me with even a hint, I’d be very grateful.
Thanks!
#include <stdio.h> #include <stdlib.h> #include 'jpeglib.h' #include <setjmp.h> int main () { // read data FILE *input = fopen('input.jpg', 'rb'); JSAMPLE *image_buffer = (JSAMPLE*) malloc(sizeof(JSAMPLE) * 640 * 480 * 3); if(input == NULL or image_buffer == NULL) exit(1); fread(image_buffer, 640 * 3, 480, input); // initialise jpeg library struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); // write to foo.jpg FILE *outfile = fopen('foo.jpg', 'wb'); if (outfile == NULL) exit(1); jpeg_stdio_dest(&cinfo, outfile); // setup library cinfo.image_width = 640; cinfo.image_height = 480; cinfo.input_components = 3; // 3 components (R, G, B) cinfo.in_color_space = JCS_RGB; // RGB jpeg_set_defaults(&cinfo); // set defaults // start compressing int row_stride = 640 * 3; // number of characters in a row JSAMPROW row_pointer[1]; // pointer to the current row data jpeg_start_compress(&cinfo, TRUE); // start compressing to jpeg while (cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride]; (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); // clean up fclose(outfile); jpeg_destroy_compress(&cinfo); }
You’re reading a JPEG file into memory (without decompressing it) and writing out that buffer as if it were uncompressed, that’s why you’re getting garbage. You need to decompress the image first before you can feed it into the JPEG compressor.
In other words, the JPEG compressor assumes that its input is raw pixels.
You can convert your input image into raw RGB using ImageMagick:
It should be exactly 921600 bytes in size.
EDIT: Your question is misleading when you state that your input JPEG file in uncompressed. Anyway, I compiled your code and it works fine, compresses the image correctly. If you can upload the file you’re using as input, it might be possible to debug further. If not, I suggest you test your program using an image created from a known JPEG using ImageMagick: