ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

transform.c
Go to the documentation of this file.
00001 /*
00002  * MSCMS - Color Management System for Wine
00003  *
00004  * Copyright 2005, 2006, 2008 Hans Leidekker
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #include "config.h"
00022 #include "wine/debug.h"
00023 
00024 #include <stdarg.h>
00025 
00026 #include "windef.h"
00027 #include "winbase.h"
00028 #include "winnls.h"
00029 #include "wingdi.h"
00030 #include "winuser.h"
00031 #include "icm.h"
00032 
00033 #include "mscms_priv.h"
00034 
00035 WINE_DEFAULT_DEBUG_CHANNEL(mscms);
00036 
00037 #ifdef HAVE_LCMS
00038 
00039 static DWORD from_profile( HPROFILE profile )
00040 {
00041     PROFILEHEADER header;
00042 
00043     GetColorProfileHeader( profile, &header );
00044     TRACE( "color space: 0x%08x %s\n", header.phDataColorSpace, MSCMS_dbgstr_tag( header.phDataColorSpace ) );
00045 
00046     switch (header.phDataColorSpace)
00047     {
00048     case 0x434d594b: return TYPE_CMYK_16;  /* 'CMYK' */
00049     case 0x47524159: return TYPE_GRAY_16;  /* 'GRAY' */
00050     case 0x4c616220: return TYPE_Lab_16;   /* 'Lab ' */
00051     case 0x52474220: return TYPE_RGB_16;   /* 'RGB ' */
00052     case 0x58595a20: return TYPE_XYZ_16;   /* 'XYZ ' */
00053     default:
00054         WARN("unhandled format\n");
00055         return TYPE_RGB_16;
00056     }
00057 }
00058 
00059 static DWORD from_bmformat( BMFORMAT format )
00060 {
00061     static int quietfixme = 0;
00062     TRACE( "bitmap format: 0x%08x\n", format );
00063 
00064     switch (format)
00065     {
00066     case BM_RGBTRIPLETS: return TYPE_RGB_8;
00067     case BM_BGRTRIPLETS: return TYPE_BGR_8;
00068     case BM_GRAY:        return TYPE_GRAY_8;
00069     default:
00070         if (quietfixme == 0)
00071         {
00072             FIXME("unhandled bitmap format 0x%x\n", format);
00073             quietfixme = 1;
00074         }
00075         return TYPE_RGB_8;
00076     }
00077 }
00078 
00079 static DWORD from_type( COLORTYPE type )
00080 {
00081     TRACE( "color type: 0x%08x\n", type );
00082 
00083     switch (type)
00084     {
00085     case COLOR_GRAY:    return TYPE_GRAY_16;
00086     case COLOR_RGB:     return TYPE_RGB_16;
00087     case COLOR_XYZ:     return TYPE_XYZ_16;
00088     case COLOR_Yxy:     return TYPE_Yxy_16;
00089     case COLOR_Lab:     return TYPE_Lab_16;
00090     case COLOR_CMYK:    return TYPE_CMYK_16;
00091     default:
00092         FIXME("unhandled color type\n");
00093         return TYPE_RGB_16;
00094     }
00095 }
00096 
00097 #endif /* HAVE_LCMS */
00098 
00099 /******************************************************************************
00100  * CreateColorTransformA            [MSCMS.@]
00101  *
00102  * See CreateColorTransformW.
00103  */
00104 HTRANSFORM WINAPI CreateColorTransformA( LPLOGCOLORSPACEA space, HPROFILE dest,
00105     HPROFILE target, DWORD flags )
00106 {
00107     LOGCOLORSPACEW spaceW;
00108     DWORD len;
00109 
00110     TRACE( "( %p, %p, %p, 0x%08x )\n", space, dest, target, flags );
00111 
00112     if (!space || !dest) return FALSE;
00113 
00114     memcpy( &spaceW, space, FIELD_OFFSET(LOGCOLORSPACEA, lcsFilename) );
00115     spaceW.lcsSize = sizeof(LOGCOLORSPACEW);
00116 
00117     len = MultiByteToWideChar( CP_ACP, 0, space->lcsFilename, -1, NULL, 0 );
00118     MultiByteToWideChar( CP_ACP, 0, space->lcsFilename, -1, spaceW.lcsFilename, len );
00119 
00120     return CreateColorTransformW( &spaceW, dest, target, flags );
00121 }
00122 
00123 /******************************************************************************
00124  * CreateColorTransformW            [MSCMS.@]
00125  *
00126  * Create a color transform.
00127  *
00128  * PARAMS
00129  *  space  [I] Input color space.
00130  *  dest   [I] Color profile of destination device.
00131  *  target [I] Color profile of target device.
00132  *  flags  [I] Flags.
00133  *
00134  * RETURNS
00135  *  Success: Handle to a transform.
00136  *  Failure: NULL
00137  */
00138 HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest,
00139     HPROFILE target, DWORD flags )
00140 {
00141     HTRANSFORM ret = NULL;
00142 #ifdef HAVE_LCMS
00143     struct transform transform;
00144     struct profile *dst, *tgt = NULL;
00145     cmsHPROFILE cmsinput, cmsoutput, cmstarget = NULL;
00146     DWORD in_format, out_format, proofing = 0;
00147     int intent;
00148 
00149     TRACE( "( %p, %p, %p, 0x%08x )\n", space, dest, target, flags );
00150 
00151     if (!space || !(dst = grab_profile( dest ))) return FALSE;
00152 
00153     if (target && !(tgt = grab_profile( target )))
00154     {
00155         release_profile( dst );
00156         return FALSE;
00157     }
00158     intent = space->lcsIntent > 3 ? INTENT_PERCEPTUAL : space->lcsIntent;
00159 
00160     TRACE( "lcsIntent:   %x\n", space->lcsIntent );
00161     TRACE( "lcsCSType:   %s\n", MSCMS_dbgstr_tag( space->lcsCSType ) );
00162     TRACE( "lcsFilename: %s\n", debugstr_w( space->lcsFilename ) );
00163 
00164     in_format  = TYPE_RGB_16;
00165     out_format = from_profile( dest );
00166 
00167     cmsinput = cmsCreate_sRGBProfile(); /* FIXME: create from supplied color space */
00168     if (target)
00169     {
00170         proofing = cmsFLAGS_SOFTPROOFING;
00171         cmstarget = tgt->cmsprofile;
00172     }
00173     cmsoutput = dst->cmsprofile;
00174     transform.cmstransform = cmsCreateProofingTransform(cmsinput, in_format, cmsoutput, out_format, cmstarget,
00175                                                         intent, INTENT_ABSOLUTE_COLORIMETRIC, proofing);
00176 
00177     ret = create_transform( &transform );
00178 
00179     if (tgt) release_profile( tgt );
00180     release_profile( dst );
00181 
00182 #endif /* HAVE_LCMS */
00183     return ret;
00184 }
00185 
00186 /******************************************************************************
00187  * CreateMultiProfileTransform      [MSCMS.@]
00188  *
00189  * Create a color transform from an array of color profiles.
00190  *
00191  * PARAMS
00192  *  profiles  [I] Array of color profiles.
00193  *  nprofiles [I] Number of color profiles.
00194  *  intents   [I] Array of rendering intents.
00195  *  flags     [I] Flags.
00196  *  cmm       [I] Profile to take the CMM from.
00197  *
00198  * RETURNS
00199  *  Success: Handle to a transform.
00200  *  Failure: NULL
00201  */ 
00202 HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofiles,
00203     PDWORD intents, DWORD nintents, DWORD flags, DWORD cmm )
00204 {
00205     HTRANSFORM ret = NULL;
00206 #ifdef HAVE_LCMS
00207     cmsHPROFILE *cmsprofiles, cmsconvert = NULL;
00208     struct transform transform;
00209     struct profile *profile0, *profile1;
00210     DWORD in_format, out_format;
00211 
00212     TRACE( "( %p, 0x%08x, %p, 0x%08x, 0x%08x, 0x%08x )\n",
00213            profiles, nprofiles, intents, nintents, flags, cmm );
00214 
00215     if (!profiles || !nprofiles || !intents) return NULL;
00216 
00217     if (nprofiles > 2)
00218     {
00219         FIXME("more than 2 profiles not supported\n");
00220         return NULL;
00221     }
00222 
00223     profile0 = grab_profile( profiles[0] );
00224     if (!profile0) return NULL;
00225     profile1 = grab_profile( profiles[1] );
00226     if (!profile1)
00227     {
00228         release_profile( profile0 );
00229         return NULL;
00230     }
00231     in_format  = from_profile( profiles[0] );
00232     out_format = from_profile( profiles[nprofiles - 1] );
00233 
00234     if (in_format != out_format)
00235     {
00236         /* insert a conversion profile for pairings that lcms doesn't handle */
00237         if (out_format == TYPE_RGB_16) cmsconvert = cmsCreate_sRGBProfile();
00238         if (out_format == TYPE_Lab_16) cmsconvert = cmsCreateLabProfile( NULL );
00239     }
00240 
00241     cmsprofiles = HeapAlloc( GetProcessHeap(), 0, (nprofiles + 1) * sizeof(cmsHPROFILE) );
00242     if (cmsprofiles)
00243     {
00244         cmsprofiles[0] = profile0->cmsprofile;
00245         if (cmsconvert)
00246         {
00247             cmsprofiles[1] = cmsconvert;
00248             cmsprofiles[2] = profile1->cmsprofile;
00249             nprofiles++;
00250         }
00251         else
00252         {
00253             cmsprofiles[1] = profile1->cmsprofile;
00254         }
00255         transform.cmstransform = cmsCreateMultiprofileTransform( cmsprofiles, nprofiles, in_format, out_format, *intents, 0 );
00256 
00257         HeapFree( GetProcessHeap(), 0, cmsprofiles );
00258         ret = create_transform( &transform );
00259     }
00260 
00261     release_profile( profile0 );
00262     release_profile( profile1 );
00263 
00264 #endif /* HAVE_LCMS */
00265     return ret;
00266 }
00267 
00268 /******************************************************************************
00269  * DeleteColorTransform             [MSCMS.@]
00270  *
00271  * Delete a color transform.
00272  *
00273  * PARAMS
00274  *  transform [I] Handle to a color transform.
00275  *
00276  * RETURNS
00277  *  Success: TRUE
00278  *  Failure: FALSE
00279  */ 
00280 BOOL WINAPI DeleteColorTransform( HTRANSFORM handle )
00281 {
00282     BOOL ret = FALSE;
00283 #ifdef HAVE_LCMS
00284 
00285     TRACE( "( %p )\n", handle );
00286 
00287     ret = close_transform( handle );
00288 
00289 #endif /* HAVE_LCMS */
00290     return ret;
00291 }
00292 
00293 /******************************************************************************
00294  * TranslateBitmapBits              [MSCMS.@]
00295  *
00296  * Perform color translation.
00297  *
00298  * PARAMS
00299  *  transform    [I] Handle to a color transform.
00300  *  srcbits      [I] Source bitmap.
00301  *  input        [I] Format of the source bitmap.
00302  *  width        [I] Width of the source bitmap.
00303  *  height       [I] Height of the source bitmap.
00304  *  inputstride  [I] Number of bytes in one scanline.
00305  *  destbits     [I] Destination bitmap.
00306  *  output       [I] Format of the destination bitmap.
00307  *  outputstride [I] Number of bytes in one scanline. 
00308  *  callback     [I] Callback function.
00309  *  data         [I] Callback data. 
00310  *
00311  * RETURNS
00312  *  Success: TRUE
00313  *  Failure: FALSE
00314  */
00315 BOOL WINAPI TranslateBitmapBits( HTRANSFORM handle, PVOID srcbits, BMFORMAT input,
00316     DWORD width, DWORD height, DWORD inputstride, PVOID destbits, BMFORMAT output,
00317     DWORD outputstride, PBMCALLBACKFN callback, ULONG data )
00318 {
00319     BOOL ret = FALSE;
00320 #ifdef HAVE_LCMS
00321     struct transform *transform = grab_transform( handle );
00322 
00323     TRACE( "( %p, %p, 0x%08x, 0x%08x, 0x%08x, 0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08x )\n",
00324            handle, srcbits, input, width, height, inputstride, destbits, output,
00325            outputstride, callback, data );
00326 
00327     if (!transform) return FALSE;
00328     cmsChangeBuffersFormat( transform->cmstransform, from_bmformat(input), from_bmformat(output) );
00329 
00330     cmsDoTransform( transform->cmstransform, srcbits, destbits, width * height );
00331     release_transform( transform );
00332     ret = TRUE;
00333 
00334 #endif /* HAVE_LCMS */
00335     return ret;
00336 }
00337 
00338 /******************************************************************************
00339  * TranslateColors              [MSCMS.@]
00340  *
00341  * Perform color translation.
00342  *
00343  * PARAMS
00344  *  transform    [I] Handle to a color transform.
00345  *  input        [I] Array of input colors.
00346  *  number       [I] Number of colors to translate.
00347  *  input_type   [I] Input color format.
00348  *  output       [O] Array of output colors.
00349  *  output_type  [I] Output color format.
00350  *
00351  * RETURNS
00352  *  Success: TRUE
00353  *  Failure: FALSE
00354  */
00355 BOOL WINAPI TranslateColors( HTRANSFORM handle, PCOLOR in, DWORD count,
00356                              COLORTYPE input_type, PCOLOR out, COLORTYPE output_type )
00357 {
00358 #ifdef HAVE_LCMS
00359     BOOL ret = TRUE;
00360     struct transform *transform = grab_transform( handle );
00361     cmsHTRANSFORM xfrm;
00362     unsigned int i;
00363 
00364     TRACE( "( %p, %p, %d, %d, %p, %d )\n", handle, in, count, input_type, out, output_type );
00365 
00366     if (!transform) return FALSE;
00367 
00368     xfrm = transform->cmstransform;
00369     cmsChangeBuffersFormat( xfrm, from_type(input_type), from_type(output_type) );
00370 
00371     switch (input_type)
00372     {
00373     case COLOR_RGB:
00374     {
00375         switch (output_type)
00376         {
00377         case COLOR_RGB:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].rgb, 1 ); goto done;
00378         case COLOR_Lab:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].Lab, 1 ); goto done;
00379         case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].gray, 1 ); goto done;
00380         case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].cmyk, 1 ); goto done;
00381         case COLOR_XYZ:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].XYZ, 1 ); goto done;
00382         default:
00383             FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
00384             ret = FALSE;
00385             break;
00386         }
00387         break;
00388     }
00389     case COLOR_Lab:
00390     {
00391         switch (output_type)
00392         {
00393         case COLOR_RGB:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].rgb, 1 ); goto done;
00394         case COLOR_Lab:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].Lab, 1 ); goto done;
00395         case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].gray, 1 ); goto done;
00396         case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].cmyk, 1 ); goto done;
00397         case COLOR_XYZ:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].XYZ, 1 ); goto done;
00398         default:
00399             FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
00400             ret = FALSE;
00401             break;
00402         }
00403         break;
00404     }
00405     case COLOR_GRAY:
00406     {
00407         switch (output_type)
00408         {
00409         case COLOR_RGB:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].rgb, 1 ); goto done;
00410         case COLOR_Lab:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].Lab, 1 ); goto done;
00411         case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].gray, 1 ); goto done;
00412         case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].cmyk, 1 ); goto done;
00413         case COLOR_XYZ:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].XYZ, 1 ); goto done;
00414         default:
00415             FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
00416             ret = FALSE;
00417             break;
00418         }
00419         break;
00420     }
00421     case COLOR_CMYK:
00422     {
00423         switch (output_type)
00424         {
00425         case COLOR_RGB:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].rgb, 1 ); goto done;
00426         case COLOR_Lab:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].Lab, 1 ); goto done;
00427         case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].gray, 1 ); goto done;
00428         case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].cmyk, 1 ); goto done;
00429         case COLOR_XYZ:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].XYZ, 1 ); goto done;
00430         default:
00431             FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
00432             ret = FALSE;
00433             break;
00434         }
00435         break;
00436     }
00437     case COLOR_XYZ:
00438     {
00439         switch (output_type)
00440         {
00441         case COLOR_RGB:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].rgb, 1 ); goto done;
00442         case COLOR_Lab:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].Lab, 1 ); goto done;
00443         case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].gray, 1 ); goto done;
00444         case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].cmyk, 1 ); goto done;
00445         case COLOR_XYZ:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].XYZ, 1 ); goto done;
00446         default:
00447             FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
00448             ret = FALSE;
00449             break;
00450         }
00451         break;
00452     }
00453     default:
00454         FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
00455         ret = FALSE;
00456         break;
00457     }
00458 
00459 done:
00460     release_transform( transform );
00461     return ret;
00462 
00463 #else  /* HAVE_LCMS */
00464     return FALSE;
00465 #endif /* HAVE_LCMS */
00466 }

Generated on Sat May 26 2012 04:18:28 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.