Пример #1
0
// This function computes the distance from each component to the next one in bytes. 
static
void ComputeIncrementsForChunky(cmsUInt32Number Format,                                 
                                cmsUInt32Number ComponentStartingOrder[], 
                                cmsUInt32Number ComponentPointerIncrements[])
{
       cmsUInt32Number channels[cmsMAXCHANNELS];
       int extra = T_EXTRA(Format);
       int nchannels = T_CHANNELS(Format);
       int total_chans = nchannels + extra;
       int i;       
       int channelSize = trueBytesSize(Format);
       int pixelSize = channelSize * total_chans;
       
	   // Sanity check
	   if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
		   return;

        memset(channels, 0, sizeof(channels));

       // Separation is independent of starting point and only depends on channel size
       for (i = 0; i < extra; i++)
              ComponentPointerIncrements[i] = pixelSize;

       // Handle do swap
       for (i = 0; i < total_chans; i++)
       {
              if (T_DOSWAP(Format)) {
                     channels[i] = total_chans - i - 1;
              }
              else {
                     channels[i] = i;
              }
       }

       // Handle swap first (ROL of positions), example CMYK -> KCMY | 0123 -> 3012
       if (T_SWAPFIRST(Format) && total_chans > 1) {
              
              cmsUInt32Number tmp = channels[0];
              for (i = 0; i < total_chans-1; i++)
                     channels[i] = channels[i + 1];

              channels[total_chans - 1] = tmp;
       }

       // Handle size
       if (channelSize > 1)
              for (i = 0; i < total_chans; i++) {
                     channels[i] *= channelSize;
              }

       for (i = 0; i < extra; i++)
              ComponentStartingOrder[i] = channels[i + nchannels];
}
Пример #2
0
//  On planar configurations, the distance is the stride added to any non-negative
static
void ComputeIncrementsForPlanar(cmsUInt32Number Format, 
                                cmsUInt32Number BytesPerPlane,
                                cmsUInt32Number ComponentStartingOrder[], 
                                cmsUInt32Number ComponentPointerIncrements[])
{
       cmsUInt32Number channels[cmsMAXCHANNELS];       
       int extra = T_EXTRA(Format);
       int nchannels = T_CHANNELS(Format);
       int total_chans = nchannels + extra;
       int i;
       int channelSize = trueBytesSize(Format);
      
       // Separation is independent of starting point and only depends on channel size
       for (i = 0; i < extra; i++)
              ComponentPointerIncrements[i] = channelSize;

       // Handle do swap
       for (i = 0; i < total_chans; i++)
       {
              if (T_DOSWAP(Format)) {
                     channels[i] = total_chans - i - 1;
              }
              else {
                     channels[i] = i;
              }
       }

       // Handle swap first (ROL of positions), example CMYK -> KCMY | 0123 -> 3012
       if (T_SWAPFIRST(Format)) {

              cmsUInt32Number tmp = channels[0];
              for (i = 0; i < total_chans - 1; i++)
                     channels[i] = channels[i + 1];

              channels[total_chans - 1] = tmp;
       }

       // Handle size
       for (i = 0; i < total_chans; i++) {
              channels[i] *= BytesPerPlane;
       }

       for (i = 0; i < extra; i++)
              ComponentStartingOrder[i] = channels[i + nchannels];
}
Пример #3
0
// Handles extra channels copying alpha if requested by the flags
void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
                             void* out, 
                             cmsUInt32Number PixelsPerLine,
                             cmsUInt32Number LineCount,
                             const cmsStride* Stride)
{
       size_t i, j, k;
       cmsUInt32Number nExtra;
       cmsUInt32Number SourceStartingOrder[cmsMAXCHANNELS];
       cmsUInt32Number SourceIncrements[cmsMAXCHANNELS];
       cmsUInt32Number DestStartingOrder[cmsMAXCHANNELS];
       cmsUInt32Number DestIncrements[cmsMAXCHANNELS];
       cmsUInt32Number SourceStrideIncrements[cmsMAXCHANNELS];
       cmsUInt32Number DestStrideIncrements[cmsMAXCHANNELS];

       cmsUInt8Number* SourcePtr[cmsMAXCHANNELS];
       cmsUInt8Number* DestPtr[cmsMAXCHANNELS];

       cmsFormatterAlphaFn copyValueFn;

       // Make sure we need some copy
       if (!(p->dwOriginalFlags & cmsFLAGS_COPY_ALPHA))
              return;

       // Make sure we have same number of alpha channels. If not, just reurn as this should be checked at transform creation time.
       nExtra = T_EXTRA(p->InputFormat);
       if (nExtra != T_EXTRA(p->OutputFormat))
              return;
       
       // Anything to do?
       if (nExtra == 0)
              return;

       // Compute the increments 
       ComputeComponentIncrements(p->InputFormat, Stride->BytesPerPlaneIn, SourceStartingOrder, SourceIncrements);
       ComputeComponentIncrements(p->OutputFormat, Stride->BytesPerPlaneOut, DestStartingOrder, DestIncrements);
    
       // Check for conversions 8, 16, half, float, dbl
       copyValueFn = _cmsGetFormatterAlpha(p->ContextID, p->InputFormat, p->OutputFormat);


       memset(SourceStrideIncrements, 0, sizeof(SourceStrideIncrements));
       memset(DestStrideIncrements, 0, sizeof(DestStrideIncrements));


       // The loop itself       
       for (i = 0; i < LineCount; i++) {

              // Prepare pointers for the loop
              for (j = 0; j < nExtra; j++)
              {
                     SourcePtr[j] = (cmsUInt8Number*)in + SourceStartingOrder[j] + SourceStrideIncrements[j];
                     DestPtr[j] = (cmsUInt8Number*)out + DestStartingOrder[j] + DestStrideIncrements[j];
              }

              for (j = 0; j < PixelsPerLine; j++) {

                     for (k = 0; k < nExtra; k++) {

                            copyValueFn(DestPtr[k], SourcePtr[k]);

                            SourcePtr[k] += SourceIncrements[k];
                            DestPtr[k] += DestIncrements[k];
                     }
              }

              for (j = 0; j < nExtra; j++) {

                     SourceStrideIncrements[j] += Stride->BytesPerLineIn;
                     DestStrideIncrements[j] += Stride->BytesPerLineOut;
              }

       }

}
Пример #4
0
static
int TransformImage(TIFF* in, TIFF* out, const char *cDefInpProf, const char *cOutProf)
{
       cmsHPROFILE hIn, hOut, hProof, hInkLimit = NULL;
       cmsHTRANSFORM xform;
       DWORD wInput, wOutput;
       int OutputColorSpace;
       int bps = (Width16 ? 2 : 1);
       DWORD dwFlags = 0;        
       int nPlanes;

    // Observer adaptation state (only meaningful on absolute colorimetric intent)

       cmsSetAdaptationState(ObserverAdaptationState);

       if (EmbedProfile && cOutProf) 
           DoEmbedProfile(out, cOutProf);


       
       if (BlackWhiteCompensation) 
            dwFlags |= cmsFLAGS_WHITEBLACKCOMPENSATION;           
       

       if (PreserveBlack) {
			dwFlags |= cmsFLAGS_PRESERVEBLACK;
			if (PrecalcMode == 0) PrecalcMode = 1;
	   }

       switch (PrecalcMode) {
           
       case 0: dwFlags |= cmsFLAGS_NOTPRECALC; break;
       case 2: dwFlags |= cmsFLAGS_HIGHRESPRECALC; break;
       case 3: dwFlags |= cmsFLAGS_LOWRESPRECALC; break;
       case 1: break;

       default: FatalError("Unknown precalculation mode '%d'", PrecalcMode);
       }
        

       if (GamutCheck)
            dwFlags |= cmsFLAGS_GAMUTCHECK;
        

       hProof = NULL;
       hOut = NULL;

       if (lIsDeviceLink) {

            hIn = cmsOpenProfileFromFile(cDefInpProf, "r");                  
       }
       else {

               hIn =  GetTIFFProfile(in);

               if (hIn == NULL)                    
                       hIn = OpenStockProfile(cDefInpProf);               
               
               hOut = OpenStockProfile(cOutProf);
                 
               if (cProofing != NULL) {

                   hProof = OpenStockProfile(cProofing);
                   dwFlags |= cmsFLAGS_SOFTPROOFING;
               }
       }

       // Take input color space

       wInput = GetInputPixelType(in);

       // Assure both, input profile and input TIFF are on same colorspace

       if (_cmsLCMScolorSpace(cmsGetColorSpace(hIn)) != (int) T_COLORSPACE(wInput))
              FatalError("Input profile is not operating in proper color space");

      
       if (!lIsDeviceLink) 
                OutputColorSpace = _cmsLCMScolorSpace(cmsGetColorSpace(hOut));
       else 
                OutputColorSpace = _cmsLCMScolorSpace(cmsGetPCS(hIn));
                
       wOutput      = ComputeOutputFormatDescriptor(wInput, OutputColorSpace, bps);

       WriteOutputTags(out, OutputColorSpace, bps);
       CopyOtherTags(in, out);

       // Ink limit
       if (InkLimit != 400.0 && 
                (OutputColorSpace == PT_CMYK || OutputColorSpace == PT_CMY)) {

           cmsHPROFILE hProfiles[10];
           int nProfiles = 0;


           hInkLimit = cmsCreateInkLimitingDeviceLink(cmsGetColorSpace(hOut), InkLimit);

           hProfiles[nProfiles++] = hIn;
           if (hProof) {
                hProfiles[nProfiles++] = hProof;
                hProfiles[nProfiles++] = hProof;
           }

           hProfiles[nProfiles++] = hOut;
           hProfiles[nProfiles++] = hInkLimit;
                   
           xform = cmsCreateMultiprofileTransform(hProfiles, nProfiles, 
                                                wInput, wOutput, Intent, dwFlags);
           
       }
       else {

		   xform = cmsCreateProofingTransform(hIn, wInput, 
											  hOut, wOutput, 
											  hProof, Intent, 
											  ProofingIntent, 
											  dwFlags);
       }

      

       // Planar stuff

       if (T_PLANAR(wInput)) 
            nPlanes = T_CHANNELS(wInput) + T_EXTRA(wInput);
       else
            nPlanes = 1;


	   // TIFF Lab of 8 bits need special handling

		if (wInput == TYPE_Lab_8 && 
			   !InputLabUsingICC &&
			   cInpProf != NULL  &&
			   stricmp(cInpProf, "*Lab") == 0) {

					cmsSetUserFormatters(xform, TYPE_Lab_8, UnrollTIFFLab8, TYPE_Lab_8, NULL); 
		}


		if (wOutput == TYPE_Lab_8 && 			   
			   cOutProf != NULL  &&
			   stricmp(cOutProf, "*Lab") == 0) {

					cmsSetUserFormatters(xform, TYPE_Lab_8, NULL, TYPE_Lab_8, PackTIFFLab8); 
		}

	   
       // Handle tile by tile or strip by strip

       if (TIFFIsTiled(in)) {

                TileBasedXform(xform, in, out, nPlanes);
       }
       else {

                StripBasedXform(xform, in, out, nPlanes);
       }


       cmsDeleteTransform(xform);
       cmsCloseProfile(hIn);
       cmsCloseProfile(hOut);
       if (hInkLimit) 
           cmsCloseProfile(hInkLimit);
       if (hProof) 
           cmsCloseProfile(hProof);


       TIFFWriteDirectory(out);

       return 1;
}