Search code examples
imageopengljpegreverselibjpeg

Image flips, OpenGL output to JPEG using libjpeg


The below code helps me to convert OpenGL output to JPEG image using libjpg but the resultant image is flipped vertical...

The code works perfect but the final image is flipped I dont know why ?!

unsigned char *pdata = new unsigned char[width*height*3];
    glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pdata);

    FILE *outfile;
    if ((outfile = fopen("sample.jpeg", "wb")) == NULL) {
        printf("can't open %s");
        exit(1);
      }

    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr       jerr;

    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    jpeg_stdio_dest(&cinfo, outfile);

    cinfo.image_width      = width;
    cinfo.image_height     = height;
    cinfo.input_components = 3;
    cinfo.in_color_space   = JCS_RGB;

    jpeg_set_defaults(&cinfo);
    /*set the quality [0..100]  */
    jpeg_set_quality (&cinfo, 100, true);
    jpeg_start_compress(&cinfo, true);

    JSAMPROW row_pointer;
    int row_stride = width * 3;

    while (cinfo.next_scanline < cinfo.image_height) {
    row_pointer = (JSAMPROW) &pdata[cinfo.next_scanline*row_stride];
    jpeg_write_scanlines(&cinfo, &row_pointer, 1);
    }

    jpeg_finish_compress(&cinfo);

    fclose(outfile);

    jpeg_destroy_compress(&cinfo);

Solution

  • OpenGL's coordinate system has the origin in the lower left corner of the image. LIBJPEG assumes that the origin of the image is in the upper left corner of the image. Make the following change to fix your code:

    while (cinfo.next_scanline < cinfo.image_height)
    {
        row_pointer = (JSAMPROW) &pdata[(cinfo.image_height-1-cinfo.next_scanline)*row_stride];
        jpeg_write_scanlines(&cinfo, &row_pointer, 1);
    }