crgbcmykcolor-profilebgr

LittleCMS library: which type of variable do I have to use during conversion from rgb (bgr) to cmyk colors


Please help to run conversion of colors in LittleCMS: I do find how to work with double, but I’m stacking with using an unsigned char. I do have BGR color in an array of unsigned char, something like this: unsigned char scanline [3] = {147, 112 220}. Values can be 0-255. As I understand LittleCMS’s docs: for this type I have to use TYPE_BGR_8 (and TYPE_CMYK_8 for output). But it does not convert in a right way – only when I used TYPE_BGR_DBL, TYPE_CMYK_DBL, converted from unsigned array to double and normalized my input array to values from 0-1 I received a right conversion. Please help to optimize my code:

1) Do I have to normalize values to 0-1?

2) Which types do I have to use in my program to exclude conversion from unsigned array to double?

My programs and outputs

1) Working in a right way:

#include <stdio.h>
#include <stdlib.h>
#include "lcms2.h"

int main (){
    cmsHPROFILE hInProfile, hOutProfile; 
    cmsHTRANSFORM hTransform; 
    hInProfile = cmsCreate_sRGBProfile();
    hOutProfile = cmsOpenProfileFromFile("/home/ab/Documents/cmyk/colorProfiles/WebCoatedSWOP2006Grade5.icc", "r");
hTransform = cmsCreateTransform(hInProfile, TYPE_BGR_DBL, hOutProfile, TYPE_CMYK_DBL, INTENT_PERCEPTUAL, 0);
cmsCloseProfile(hInProfile);
cmsCloseProfile(hOutProfile);

                unsigned char scanline0[3] = {147, 112, 220};
                double scanline [3], outputline [4];

                for(int k=0;k<3;k++){
                    scanline [k] = (double)scanline0 [k]/255;
                }

                printf("Red = %f \n",scanline  [2]);
                printf("Green = %f \n", scanline [1]);
                printf("Blue = %f \n \n", scanline [0]);

                cmsDoTransform(hTransform, scanline, outputline, 1); //transforming from one to other

                printf(" Cyan %f\n Mageta %f\n Yellow %f\n Black %f\n ", outputline[0], outputline[1], outputline[2], outputline[3]); //C M Y K

    return 0;
}

Output:

Red = 0.862745 
Green = 0.439216 
Blue = 0.576471 

 Cyan 15.350576
 Mageta 68.361944
 Yellow 25.549707
 Black 1.419089

2) When I’m using an unsigned char, it works in a wrong way. Program:

hTransform = cmsCreateTransform(hInProfile, TYPE_BGR_8, hOutProfile, TYPE_CMYK_8, INTENT_PERCEPTUAL, 0);

...
                unsigned char scanline[3] = {147, 112, 220}, outputline [4];

                printf("Red = %d \n",scanline  [2]);
                printf("Green = %d \n", scanline [1]);
                printf("Blue = %d \n \n", scanline [0]);

                cmsDoTransform(hTransform, scanline, outputline, 1);

Output:

Red = 220 
Green = 112 
Blue = 147 

 Cyan 39
 Mageta 174
 Yellow 65
 Black 4

Solution

  • Answers are:

    1) There no need of normilizing. if you are working with BYTE (unsigned char). In this case values are in range from 0 to 255. If we are working with double (DBL), than we have to normalize values:

    RGB (BGR) = 0...1, and CMYK = 0.0 ... 100.0.

    2) We can use both variant.