Search code examples
clibjpeg

libjpeg reads a scanline 1/8th the original width


I am trying to just read every pixel in a jpeg image. When I read a scanline, it appears that the image has been squashed to one eighth the size of the original image. The scanline is the correct width but the remaining 7/8'ths of the scanline are not filled (0, 0, 0).

I cant simply use each pixel 8 times since a large amount of information was lost.

I don't use any decompression parameters and am perfectly happy with the defaults. The Libjpeg version I am using is "libjpeg/9d" from the https://conan.io package center.

How can I get scanlines in the correct aspect ratio?

FILE* file_p = openfile(fileaddress);
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr err; //the error handler
cinfo.err = jpeg_std_error( &err ); 
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, file_p);
int result = jpeg_read_header(&cinfo, TRUE);
bool startedfine = jpeg_start_decompress(&cinfo);
int row_stride = cinfo.output_width * cinfo.output_components;
image output = create_image(cinfo.output_width, cinfo.output_height);
JSAMPARRAY buffer = calloc(1, sizeof(JSAMPROW*));
buffer[0] = calloc(1, sizeof(JSAMPROW) * row_stride);

while (cinfo.output_scanline < cinfo.output_height) {
    int current_y = cinfo.output_scanline;
    jpeg_read_scanlines(&cinfo, buffer, 1);
    JSAMPROW row = buffer[0];

    for(int row_i = 0; row_i < row_stride; row_i += 3) {
        int r = (int)row[row_i];
        int g = (int)row[row_i + 1];
        int b = (int)row[row_i + 2];
        int actual_x = row_i / 3;
        output.pixels_array_2d[actual_x][current_y].r = r;
        output.pixels_array_2d[actual_x][current_y].g = b;
        output.pixels_array_2d[actual_x][current_y].b = g;
    }
}
free(buffer[0]);
free(buffer);
jpeg_finish_decompress(&cinfo);  
jpeg_destroy_decompress(&cinfo);
fclose(file_p);

As a side note, you may notice I assign the blue value to the green value when copying the pixels. This is because without it, my test image is the wrong colour and I don't know why.


Solution

  • The problem was I needed to call the tjDecompress2 function and give the correct pitch value as argument.

    tjDecompress2(
        handle,
        jpegBuffer,
        jpegSize,
        scaledBuffer,
        scaledWidth,
        0,
        scaledHeight,
        pixelFormat,
        flags);
    

    Here is a link to the libraries documentation on this parameter.