Menu

#117 Bugfix: Color Profile is actually still there

None
closed
None
5
2018-07-31
2016-03-16
No

To reproduce:
Load a cmyk tiff, containing a color profile, using the default options. Save it as another file. Open the new file in PS or FreeImage - the origin profile is still there, though the image is now rgb (converted when loading). PS (and any color management lib) reports an error.

The problem is Metadata contains color profile as well, even if we don't have data in a FIICCPROFILE.

To solve this:

In TIFF Load (notice, metadata is read now befor setting the icc):

   // copy TIFF metadata (must be done after FreeImage_Allocate)

    ReadMetadata(tif, dib);

    // copy ICC profile data (must be done after FreeImage_Allocate)

    FreeImage_CreateICCProfile(dib, iccBuf, iccSize);       
    if (photometric == PHOTOMETRIC_SEPARATED ) {
      if(asCMYK)
        FreeImage_GetICCProfile(dib)->flags |= FIICC_COLOR_IS_CMYK;
      else 
        FreeImage_SetMetadata(FIMD_EXIF_MAIN, dib, "InterColorProfile", NULL);
    }           

In JPEG, in section else if((cinfo.out_color_space == JCS_CMYK) && ((flags & JPEG_CMYK) == JPEG_CMYK))
add FreeImage_SetMetadata(FIMD_EXIF_MAIN, dib, "InterColorProfile", NULL);

About the PSD, I am not sure, it should be fixed as well.

Lastly, FreeImage_DestroyICCProfile (in BtimapAccess.cpp) must also have FreeImage_SetMetadata(FIMD_EXIF_MAIN, dib, "InterColorProfile", NULL);

Discussion

  • Mihail Naydenov

    Mihail Naydenov - 2016-03-16

    Ok TIFF should be

        // copy ICC profile data (must be done after FreeImage_Allocate)
    
            FreeImage_CreateICCProfile(dib, iccBuf, iccSize);       
            if (photometric == PHOTOMETRIC_SEPARATED && asCMYK) {
                  FreeImage_GetICCProfile(dib)->flags |= FIICC_COLOR_IS_CMYK;
            }           
    
            // copy TIFF metadata (must be done after FreeImage_Allocate)
    
            ReadMetadata(tif, dib);
    
        if (photometric == PHOTOMETRIC_SEPARATED && !asCMYK) 
          FreeImage_SetMetadata(FIMD_EXIF_MAIN, dib, "InterColorProfile", NULL);
    

    ReadMetadata (tiff_read_exif_profile(tiff, dib) specifically) messes the icc profile data, so it should be after profile creation!

     
  • Hervé Drolon

    Hervé Drolon - 2016-03-20
    • status: open --> pending
    • assigned_to: Hervé Drolon
    • Group: -->
     
  • Hervé Drolon

    Hervé Drolon - 2016-03-20

    Hi Mihail,

    I've fixed the TIFF plugin and also the FreeImage_DestroyICCProfile function.
    However I'm not sure about the JPEG plugin fix. Can you attach the modified JPEG plugin ?

    Hervé

     
  • Mihail Naydenov

    Mihail Naydenov - 2016-03-21

    My code is based on an very old CVS version, here is the section with more context:

                // step 7a: while (scan lines remain to be read) jpeg_read_scanlines(...);
    
                if((cinfo.out_color_space == JCS_CMYK) && ((flags & JPEG_CMYK) != JPEG_CMYK)) {
                    // convert from CMYK to RGB
    
                    JSAMPARRAY buffer;      // output row buffer
                    unsigned row_stride;    // physical row width in output buffer
    
                    // JSAMPLEs per row in output buffer
                    row_stride = cinfo.output_width * cinfo.output_components;
                    // make a one-row-high sample array that will go away when done with image
                    buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
    
                    while (cinfo.output_scanline < cinfo.output_height) {
                        JSAMPROW src = buffer[0];
                        JSAMPROW dst = FreeImage_GetScanLine(dib, cinfo.output_height - cinfo.output_scanline - 1);
    
                        jpeg_read_scanlines(&cinfo, buffer, 1);
    
                        for(unsigned x = 0; x < cinfo.output_width; x++) {
                            WORD K = (WORD)src[3];
                            dst[FI_RGBA_RED]   = (BYTE)((K * src[0]) / 255);    // C -> R
                            dst[FI_RGBA_GREEN] = (BYTE)((K * src[1]) / 255);    // M -> G
                            dst[FI_RGBA_BLUE]  = (BYTE)((K * src[2]) / 255);    // Y -> B
                            src += 4;
                            dst += 3;
                        }
    
                    }
    
            FreeImage_SetMetadata(FIMD_EXIF_MAIN, dib, "InterColorProfile", NULL);
                }
    

    The section is where we convert CMYK to RGB. In that case the profile will be incorrect. In my original post the section I mention is wrong.

     
  • Hervé Drolon

    Hervé Drolon - 2016-04-10

    OK, JPEG plugin fixed in the CVS

     
  • Hervé Drolon

    Hervé Drolon - 2018-07-31
    • status: pending --> closed
     
  • Hervé Drolon

    Hervé Drolon - 2018-07-31

    Fixed in release 3.18.0

     

Anonymous
Anonymous

Add attachments
Cancel