Hi Marti, just tried your suggestion and it works perfectly now - was something wrong with the formatter.
This is the modified code creating the formatter for reference: cmsColorSpaceSignature outputColorSpace = cmsGetColorSpace(hOutProfile); cout << "Colorspace of the output profile: " << hex << (int)outputColorSpace << dec << endl; int nNumOutputChannels = cmsChannelsOf(outputColorSpace); int nOutputFormatter = BYTES_SH(1) | CHANNELS_SH(nNumOutputChannels); nOutputFormatter |= COLORSPACE_SH(_cmsLCMScolorSpace(outputColorSpace)); int nNumBytes = T_BYTES(nOutputFormatter); cout << "Output Profile has " << nNumOutputChannels << " channels each with " << nNumBytes << " Bytes." << endl; Thanks a ton Michael > > Hi Michael, > > I think you are assuming T_BYTES() returns the number of bytes per > pixel when it really returns bytes per channel. Also, you are mixing > cmsColorSpaceSignature with formatters. > > Just use this: > > nOutputFormatter = BYTES_SH(1) | CHANNELS_SH(nNumOutputChannels); > > This is enough. You can do an additional colorspace check by using > > nOutputFormatter |= > COLORSPACE_SH(_cmsLCMScolorSpace((cmsColorSpaceSignature(hProfile))); > > Plese note the "_" at the begin of _cmsLCMScolorSpace, and that means > you should not need this function in normal operation. If fact, the > colorspace (color model to be more precise) of the image is not given > by the profile but by the image itself. As an example, I can embed a > RGB profile into a CMYK image. Using the algorithm above would not > work. I would check both color models to validate the profile before > proceeding to do the color transformation. > > Regards > Marti > > > > > Quoting Michael Zauner <psychotro...@gmx.ch>: > >> Hi, >> >> I do love little CMS very much - nice, small and quick. >> But I do have an issue with a bit of code and I cannot see what I am >> doing wrong. >> Maybe one of you guys could help me and tell if I do anything obvious >> stupid? >> >> The basic idea is that I do have an image with an embedded profile and >> an external profile file. >> The external profile can differ and may have e.g. 6 channels. >> I want to transform the image with the external profile and read the >> pixel values of the output channels. >> >> Here is an example code (leaving out only the input image specific >> stuff), which is really a modified version of the basic example seen in >> the tutorial: >> >> //START >> >> cmsHPROFILE hInProfile, hOutProfile; >> cmsHTRANSFORM hTransform; >> >> //Width and height and pixel type are from the input image >> int nInputPixelType = TYPE_BGRA_16; >> int nWidth = xxx; >> int nHeight = xxx; >> >> //Loading the profiles >> hInProfile = cmsOpenProfileFromMem(memoryPointer,size); >> hOutProfile = cmsOpenProfileFromFile(szProfileFile, "r"); >> >> //Extracting information of the output profile >> cmsColorSpaceSignature outputColorSpace = cmsGetColorSpace(hOutProfile); >> int nNumOutputChannels = cmsChannelsOf(outputColorSpace); //This is 6 in >> my example >> //This formatter is used in the transformation >> int nOutputFormatter = _cmsLCMScolorSpace(outputColorSpace); >> int nNumBytes = T_BYTES(nOutputFormatter); //This is 4 in my example >> >> //I change now the formatter to have 1 byte instead as I want to use >> that instead of 4 byte precision >> if(nNumBytes != 1) >> { >> //Clear the first 3 bits >> nOutputFormatter &= ~7; >> //Set it to 1 Bytes >> nOutputFormatter |= 1; >> //Retrieve the value again (making sure it is one byte) >> nNumBytes = T_BYTES(nOutputFormatter); >> } >> >> //Create the transformation >> hTransform = cmsCreateTransform(hInProfile, nInputPixelType, >> hOutProfile, nOutputFormatter, >> INTENT_RELATIVE_COLORIMETRIC, 0); >> >> //Closing the profile >> cmsCloseProfile(hInProfile); >> cmsCloseProfile(hOutProfile); >> >> //Create a buffer to hold the transformed data >> int nNewSizeInBytes = nNumOutputChannels * nHeight * nWidth * nNumBytes; >> char* szData = new char[nNewSizeInBytes]; >> memset(szData,0,nNewSizeInBytes); >> >> //Transform the data >> int nRowLengthInBytes = nNumOutputChannels*nNumBytes*nWidth; >> for(int i = 0; i < nHeight; ++i) >> { >> char* pixelBuffer = READ_BUFFER_FROM_IMAGE_FOR_ROW(i); >> cmsDoTransform(hTransform, pixelBuffer,szData + i >> *nRowLengthInBytes, nWidth); >> } >> >> //END >> >> The issue is that the transformation does work - I do get the data for >> each channel. But the transformed image data is only 1/3 wide (the >> height does match) - the other 2/3 of the image are untouched (e.g. when >> I initialize szData with white instead of black, it remains white). >> I must be doing something really stupid - but I cannot see what is >> wrong? >> >> Any help or pointers are highly appriciated. >> It would help me to know if the litte CMS code is ok but I have an issue >> either in the input buffer or the output buffer? >> >> Thank you very much in advance >> >> Michael >> >> ------------------------------------------------------------------------------ >> >> >> Try New Relic Now & We'll Send You this Cool Shirt >> New Relic is the only SaaS-based application performance monitoring >> service >> that delivers powerful full stack analytics. Optimize and monitor your >> browser, app, & servers with just a few lines of code. Try New Relic >> and get this awesome Nerd Life shirt! >> http://p.sf.net/sfu/newrelic_d2d_may >> _______________________________________________ >> Lcms-user mailing list >> Lcms-user@lists.sourceforge.net >> https://lists.sourceforge.net/lists/listinfo/lcms-user >> > > > > ------------------------------------------------------------------------------ Try New Relic Now & We'll Send You this Cool Shirt New Relic is the only SaaS-based application performance monitoring service that delivers powerful full stack analytics. Optimize and monitor your browser, app, & servers with just a few lines of code. Try New Relic and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_may _______________________________________________ Lcms-user mailing list Lcms-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lcms-user