jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c
changeset 2 90ce3da70b43
child 2392 738be5224b3f
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     3  *
       
     4  * This code is free software; you can redistribute it and/or modify it
       
     5  * under the terms of the GNU General Public License version 2 only, as
       
     6  * published by the Free Software Foundation.  Sun designates this
       
     7  * particular file as subject to the "Classpath" exception as provided
       
     8  * by Sun in the LICENSE file that accompanied this code.
       
     9  *
       
    10  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    13  * version 2 for more details (a copy is included in the LICENSE file that
       
    14  * accompanied this code).
       
    15  *
       
    16  * You should have received a copy of the GNU General Public License version
       
    17  * 2 along with this work; if not, write to the Free Software Foundation,
       
    18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    19  *
       
    20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    21  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    22  * have any questions.
       
    23  */
       
    24 
       
    25 // This file is available under and governed by the GNU General Public
       
    26 // License version 2 only, as published by the Free Software Foundation.
       
    27 // However, the following notice accompanied the original version of this
       
    28 // file:
       
    29 //
       
    30 //
       
    31 //  Little cms
       
    32 //  Copyright (C) 1998-2006 Marti Maria
       
    33 //
       
    34 // Permission is hereby granted, free of charge, to any person obtaining
       
    35 // a copy of this software and associated documentation files (the "Software"),
       
    36 // to deal in the Software without restriction, including without limitation
       
    37 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
       
    38 // and/or sell copies of the Software, and to permit persons to whom the Software
       
    39 // is furnished to do so, subject to the following conditions:
       
    40 //
       
    41 // The above copyright notice and this permission notice shall be included in
       
    42 // all copies or substantial portions of the Software.
       
    43 //
       
    44 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
       
    45 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
       
    46 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
       
    47 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
       
    48 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
       
    49 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
       
    50 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
       
    51 //
       
    52 
       
    53 // Generic I/O, tag dictionary management, profile struct
       
    54 
       
    55 
       
    56 
       
    57 #include "lcms.h"
       
    58 
       
    59 
       
    60 // Memory-based stream ---------------------------------------------------
       
    61 
       
    62 typedef struct {
       
    63                 LPBYTE Block;           // Points to allocated memory
       
    64                 size_t Size;            // Size of allocated memory
       
    65                 int Pointer;            // Points to current location
       
    66                 int FreeBlockOnClose;   // As title
       
    67 
       
    68                 } FILEMEM;
       
    69 
       
    70 static
       
    71 LPVOID MemoryOpen(LPBYTE Block, size_t Size, char Mode)
       
    72 {
       
    73     FILEMEM* fm = (FILEMEM*) malloc(sizeof(FILEMEM));
       
    74     ZeroMemory(fm, sizeof(FILEMEM));
       
    75 
       
    76     if (Mode == 'r') {
       
    77 
       
    78         fm ->Block   = (LPBYTE) malloc(Size);
       
    79         if (fm ->Block == NULL) {
       
    80             free(fm);
       
    81             return NULL;
       
    82         }
       
    83 
       
    84 
       
    85         CopyMemory(fm->Block, Block, Size);
       
    86         fm ->FreeBlockOnClose = TRUE;
       
    87     }
       
    88     else {
       
    89         fm ->Block = Block;
       
    90         fm ->FreeBlockOnClose = FALSE;
       
    91     }
       
    92 
       
    93     fm ->Size    = Size;
       
    94     fm ->Pointer = 0;
       
    95 
       
    96     return (LPVOID) fm;
       
    97 }
       
    98 
       
    99 
       
   100 static
       
   101 size_t MemoryRead(LPVOID buffer, size_t size, size_t count, struct _lcms_iccprofile_struct* Icc)
       
   102 {
       
   103      FILEMEM* ResData = (FILEMEM*) Icc ->stream;
       
   104      LPBYTE Ptr;
       
   105      size_t len = size * count;
       
   106 
       
   107 
       
   108      if (ResData -> Pointer + len > ResData -> Size){
       
   109 
       
   110          len = (ResData -> Size - ResData -> Pointer);
       
   111          cmsSignalError(LCMS_ERRC_WARNING, "Read from memory error. Got %d bytes, block should be of %d bytes", len * size, count * size);
       
   112 
       
   113      }
       
   114 
       
   115     Ptr  = ResData -> Block;
       
   116     Ptr += ResData -> Pointer;
       
   117     CopyMemory(buffer, Ptr, len);
       
   118     ResData -> Pointer += (int) len;
       
   119 
       
   120     return count;
       
   121 }
       
   122 
       
   123 // SEEK_CUR is assumed
       
   124 
       
   125 static
       
   126 BOOL MemorySeek(struct _lcms_iccprofile_struct* Icc, size_t offset)
       
   127 {
       
   128     FILEMEM* ResData = (FILEMEM*) Icc ->stream;
       
   129 
       
   130     if (offset > ResData ->Size) {
       
   131          cmsSignalError(LCMS_ERRC_ABORTED,  "Pointer error; probably corrupted file");
       
   132          return TRUE;
       
   133     }
       
   134 
       
   135     ResData ->Pointer = (DWORD) offset;
       
   136     return FALSE;
       
   137 }
       
   138 
       
   139 // FTell
       
   140 
       
   141 static
       
   142 size_t MemoryTell(struct _lcms_iccprofile_struct* Icc)
       
   143 {
       
   144     FILEMEM* ResData = (FILEMEM*) Icc ->stream;
       
   145 
       
   146     return ResData -> Pointer;
       
   147 }
       
   148 
       
   149 
       
   150 // Writes data to memory, also keeps used space for further reference
       
   151 
       
   152 static
       
   153 BOOL MemoryWrite(struct _lcms_iccprofile_struct* Icc, size_t size, void *Ptr)
       
   154 {
       
   155         FILEMEM* ResData = (FILEMEM*) Icc ->stream;
       
   156 
       
   157        if (size == 0) return TRUE;
       
   158 
       
   159        if (ResData != NULL)
       
   160            CopyMemory(ResData ->Block + Icc ->UsedSpace, Ptr, size);
       
   161 
       
   162        Icc->UsedSpace += size;
       
   163 
       
   164        return TRUE;
       
   165 }
       
   166 
       
   167 
       
   168 static
       
   169 BOOL MemoryClose(struct _lcms_iccprofile_struct* Icc)
       
   170 {
       
   171     FILEMEM* ResData = (FILEMEM*) Icc ->stream;
       
   172 
       
   173     if (ResData ->FreeBlockOnClose) {
       
   174 
       
   175         if (ResData ->Block) free(ResData ->Block);
       
   176     }
       
   177     free(ResData);
       
   178     return 0;
       
   179 }
       
   180 
       
   181 
       
   182 // File-based stream -------------------------------------------------------
       
   183 
       
   184 static
       
   185 LPVOID FileOpen(const char* filename)
       
   186 {
       
   187     return (void*) fopen(filename, "rb");
       
   188 }
       
   189 
       
   190 static
       
   191 size_t FileRead(void *buffer, size_t size, size_t count, struct _lcms_iccprofile_struct* Icc)
       
   192 {
       
   193     size_t nReaded = fread(buffer, size, count, (FILE*) Icc->stream);
       
   194     if (nReaded != count) {
       
   195             cmsSignalError(LCMS_ERRC_WARNING, "Read error. Got %d bytes, block should be of %d bytes", nReaded * size, count * size);
       
   196             return 0;
       
   197     }
       
   198 
       
   199     return nReaded;
       
   200 }
       
   201 
       
   202 
       
   203 static
       
   204 BOOL FileSeek(struct _lcms_iccprofile_struct* Icc, size_t offset)
       
   205 {
       
   206     if (fseek((FILE*) Icc ->stream, (long) offset, SEEK_SET) != 0) {
       
   207 
       
   208        cmsSignalError(LCMS_ERRC_ABORTED, "Seek error; probably corrupted file");
       
   209        return TRUE;
       
   210     }
       
   211 
       
   212     return FALSE;
       
   213 }
       
   214 
       
   215 
       
   216 static
       
   217 size_t FileTell(struct _lcms_iccprofile_struct* Icc)
       
   218 {
       
   219     return ftell((FILE*) Icc ->stream);
       
   220 }
       
   221 
       
   222 // Writes data to stream, also keeps used space for further reference
       
   223 
       
   224 
       
   225 static
       
   226 BOOL FileWrite(struct _lcms_iccprofile_struct* Icc, size_t size, LPVOID Ptr)
       
   227 {
       
   228        if (size == 0) return TRUE;
       
   229 
       
   230        Icc->UsedSpace += size;
       
   231 
       
   232        if (Icc->stream == NULL) {
       
   233 
       
   234               return TRUE;
       
   235        }
       
   236 
       
   237        return (fwrite(Ptr, size, 1, (FILE*) Icc->stream) == 1);
       
   238 }
       
   239 
       
   240 
       
   241 static
       
   242 BOOL FileClose(struct _lcms_iccprofile_struct* Icc)
       
   243 {
       
   244     return fclose((FILE*) Icc ->stream);
       
   245 }
       
   246 
       
   247 // ----------------------------------------------------------------------------------------------------
       
   248 
       
   249 
       
   250 // Creates an empty structure holding all required parameters
       
   251 
       
   252 cmsHPROFILE _cmsCreateProfilePlaceholder(void)
       
   253 {
       
   254 
       
   255     LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) malloc(sizeof(LCMSICCPROFILE));
       
   256     if (Icc == NULL) return NULL;
       
   257 
       
   258     // Empty values
       
   259     ZeroMemory(Icc, sizeof(LCMSICCPROFILE));
       
   260 
       
   261     // Make sure illuminant is correct
       
   262     Icc ->Illuminant = *cmsD50_XYZ();
       
   263 
       
   264     // Set it to empty
       
   265     Icc -> TagCount   = 0;
       
   266 
       
   267     // Return the handle
       
   268     return (cmsHPROFILE) Icc;
       
   269 }
       
   270 
       
   271 
       
   272 // Return the number of tags
       
   273 icInt32Number LCMSEXPORT cmsGetTagCount(cmsHPROFILE hProfile)
       
   274 {
       
   275     LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile;
       
   276     return  Icc->TagCount;
       
   277 }
       
   278 
       
   279 // Return the tag signature of a given tag number
       
   280 icTagSignature LCMSEXPORT cmsGetTagSignature(cmsHPROFILE hProfile, icInt32Number n)
       
   281 {
       
   282     LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile;
       
   283 
       
   284     if (n < 0 || n > Icc->TagCount) return (icTagSignature) 0;  // Mark as not available
       
   285 
       
   286     return Icc ->TagNames[n];
       
   287 }
       
   288 
       
   289 
       
   290 // Search for a specific tag in tag dictionary
       
   291 // Returns position or -1 if tag not found
       
   292 
       
   293 icInt32Number _cmsSearchTag(LPLCMSICCPROFILE Profile, icTagSignature sig, BOOL lSignalError)
       
   294 {
       
   295        icInt32Number i;
       
   296 
       
   297        if (sig == 0) return -1;     // 0 identifies a special tag holding raw memory.
       
   298 
       
   299        for (i=0; i < Profile -> TagCount; i++) {
       
   300 
       
   301               if (sig == Profile -> TagNames[i])
       
   302                             return i;
       
   303        }
       
   304 
       
   305        if (lSignalError)
       
   306             cmsSignalError(LCMS_ERRC_ABORTED, "Tag '%lx' not found", sig);
       
   307 
       
   308        return -1;
       
   309 }
       
   310 
       
   311 
       
   312 // Check existance
       
   313 
       
   314 BOOL LCMSEXPORT cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig)
       
   315 {
       
   316        LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
       
   317        return _cmsSearchTag(Icc, sig, FALSE) >= 0;
       
   318 }
       
   319 
       
   320 
       
   321 
       
   322 // Search for a particular tag, replace if found or add new one else
       
   323 
       
   324 LPVOID _cmsInitTag(LPLCMSICCPROFILE Icc, icTagSignature sig, size_t size, const void* Init)
       
   325 {
       
   326     LPVOID Ptr;
       
   327     icInt32Number i;
       
   328 
       
   329     i = _cmsSearchTag(Icc, sig, FALSE);
       
   330 
       
   331     if (i >=0) {
       
   332 
       
   333         if (Icc -> TagPtrs[i]) free(Icc -> TagPtrs[i]);
       
   334     }
       
   335     else  {
       
   336 
       
   337         i = Icc -> TagCount;
       
   338         Icc -> TagCount++;
       
   339 
       
   340         if (Icc ->TagCount >= MAX_TABLE_TAG) {
       
   341 
       
   342             cmsSignalError(LCMS_ERRC_ABORTED, "Too many tags (%d)", MAX_TABLE_TAG);
       
   343             Icc ->TagCount = MAX_TABLE_TAG-1;
       
   344         }
       
   345     }
       
   346 
       
   347 
       
   348     Ptr = malloc(size);
       
   349     CopyMemory(Ptr, Init, size);
       
   350 
       
   351     Icc ->TagNames[i] = sig;
       
   352     Icc ->TagSizes[i] = size;
       
   353     Icc ->TagPtrs[i]  = Ptr;
       
   354 
       
   355     return Ptr;
       
   356 }
       
   357 
       
   358 
       
   359 
       
   360 
       
   361 
       
   362 // Creates a profile from file read placeholder
       
   363 
       
   364 LPLCMSICCPROFILE _cmsCreateProfileFromFilePlaceholder(const char* FileName)
       
   365 {
       
   366     LPLCMSICCPROFILE NewIcc;
       
   367     LPVOID ICCfile = FileOpen(FileName);
       
   368 
       
   369     if (ICCfile == NULL) {
       
   370 
       
   371               cmsSignalError(LCMS_ERRC_ABORTED, "File '%s' not found", FileName);
       
   372               return NULL;
       
   373     }
       
   374 
       
   375     NewIcc = (LPLCMSICCPROFILE) _cmsCreateProfilePlaceholder();
       
   376     if (NewIcc == NULL) return NULL;
       
   377 
       
   378     strncpy(NewIcc -> PhysicalFile, FileName, MAX_PATH-1);
       
   379     NewIcc ->stream = ICCfile;
       
   380 
       
   381     NewIcc ->Read  = FileRead;
       
   382     NewIcc ->Seek  = FileSeek;
       
   383     NewIcc ->Tell  = FileTell;
       
   384     NewIcc ->Close = FileClose;
       
   385     NewIcc ->Write = NULL;
       
   386 
       
   387     NewIcc ->IsWrite = FALSE;
       
   388 
       
   389 
       
   390 
       
   391 
       
   392     return NewIcc;
       
   393 }
       
   394 
       
   395 
       
   396 // Creates a profile from memory read placeholder
       
   397 
       
   398 LPLCMSICCPROFILE _cmsCreateProfileFromMemPlaceholder(LPVOID MemPtr, DWORD dwSize)
       
   399 {
       
   400 
       
   401     LPLCMSICCPROFILE NewIcc;
       
   402     LPVOID ICCfile = MemoryOpen((LPBYTE) MemPtr, (size_t) dwSize, 'r');
       
   403 
       
   404 
       
   405     if (ICCfile == NULL) {
       
   406 
       
   407         cmsSignalError(LCMS_ERRC_ABORTED, "Couldn't allocate %ld bytes for profile", dwSize);
       
   408         return NULL;
       
   409     }
       
   410 
       
   411 
       
   412     NewIcc = (LPLCMSICCPROFILE) _cmsCreateProfilePlaceholder();
       
   413     if (NewIcc == NULL) return NULL;
       
   414 
       
   415     NewIcc -> PhysicalFile[0] = 0;
       
   416     NewIcc ->stream = ICCfile;
       
   417 
       
   418     NewIcc ->Read  = MemoryRead;
       
   419     NewIcc ->Seek  = MemorySeek;
       
   420     NewIcc ->Tell  = MemoryTell;
       
   421     NewIcc ->Close = MemoryClose;
       
   422     NewIcc ->Write = NULL;
       
   423 
       
   424     NewIcc ->IsWrite = FALSE;
       
   425 
       
   426 
       
   427     return NewIcc;
       
   428 }
       
   429 
       
   430 
       
   431 // Turn a placeholder into file writter
       
   432 
       
   433 void _cmsSetSaveToDisk(LPLCMSICCPROFILE Icc, const char* FileName)
       
   434 {
       
   435 
       
   436     if (FileName == NULL) {
       
   437 
       
   438           Icc ->stream = NULL;
       
   439     }
       
   440     else {
       
   441 
       
   442           Icc ->stream = fopen(FileName, "wb");
       
   443           if (Icc ->stream == NULL)
       
   444                 cmsSignalError(LCMS_ERRC_ABORTED, "Couldn't write to file '%s'", FileName);
       
   445     }
       
   446 
       
   447     Icc ->Write = FileWrite;   // Save to disk
       
   448     Icc ->Close = FileClose;
       
   449 }
       
   450 
       
   451 
       
   452 
       
   453 // Turn a  placeholder into memory writter
       
   454 
       
   455 void _cmsSetSaveToMemory(LPLCMSICCPROFILE Icc, LPVOID MemPtr, size_t dwSize)
       
   456 {
       
   457 
       
   458     if (MemPtr == NULL) {
       
   459 
       
   460         Icc ->stream = NULL;
       
   461     }
       
   462     else {
       
   463 
       
   464         Icc ->stream = (FILEMEM*) MemoryOpen((LPBYTE) MemPtr, dwSize, 'w');
       
   465         if (Icc ->stream == NULL)
       
   466                 cmsSignalError(LCMS_ERRC_ABORTED, "Couldn't write to memory");
       
   467     }
       
   468 
       
   469     Icc ->Write = MemoryWrite;
       
   470     Icc ->Close = MemoryClose;
       
   471 }
       
   472 
       
   473 
       
   474 // ----------------------------------------------------------------------- Set/Get several struct members
       
   475 
       
   476 
       
   477 
       
   478 
       
   479 BOOL LCMSEXPORT cmsTakeMediaWhitePoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
       
   480 {
       
   481      LPLCMSICCPROFILE    Icc = (LPLCMSICCPROFILE) hProfile;
       
   482      *Dest = Icc -> MediaWhitePoint;
       
   483      return TRUE;
       
   484 }
       
   485 
       
   486 
       
   487 BOOL LCMSEXPORT cmsTakeMediaBlackPoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
       
   488 {
       
   489       LPLCMSICCPROFILE    Icc = (LPLCMSICCPROFILE) hProfile;
       
   490       *Dest = Icc -> MediaBlackPoint;
       
   491       return TRUE;
       
   492 }
       
   493 
       
   494 BOOL  LCMSEXPORT cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
       
   495 {
       
   496        LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
       
   497        *Dest = Icc -> Illuminant;
       
   498        return TRUE;
       
   499 }
       
   500 
       
   501 int LCMSEXPORT cmsTakeRenderingIntent(cmsHPROFILE hProfile)
       
   502 {
       
   503        LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
       
   504        return (int) Icc -> RenderingIntent;
       
   505 }
       
   506 
       
   507 void LCMSEXPORT cmsSetRenderingIntent(cmsHPROFILE hProfile, int RenderingIntent)
       
   508 {
       
   509     LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
       
   510     Icc -> RenderingIntent = (icRenderingIntent) RenderingIntent;
       
   511 }
       
   512 
       
   513 
       
   514 DWORD LCMSEXPORT cmsTakeHeaderFlags(cmsHPROFILE hProfile)
       
   515 {
       
   516        LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
       
   517        return (DWORD) Icc -> flags;
       
   518 }
       
   519 
       
   520 void LCMSEXPORT cmsSetHeaderFlags(cmsHPROFILE hProfile, DWORD Flags)
       
   521 {
       
   522     LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
       
   523     Icc -> flags = (icUInt32Number) Flags;
       
   524 }
       
   525 
       
   526 DWORD LCMSEXPORT cmsTakeHeaderAttributes(cmsHPROFILE hProfile)
       
   527 {
       
   528        LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
       
   529        return (DWORD) Icc -> attributes;
       
   530 }
       
   531 
       
   532 void LCMSEXPORT cmsSetHeaderAttributes(cmsHPROFILE hProfile, DWORD Flags)
       
   533 {
       
   534     LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
       
   535     Icc -> attributes = (icUInt32Number) Flags;
       
   536 }
       
   537 
       
   538 
       
   539 const BYTE* LCMSEXPORT cmsTakeProfileID(cmsHPROFILE hProfile)
       
   540 {
       
   541     LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
       
   542     return Icc ->ProfileID;
       
   543 }
       
   544 
       
   545 void LCMSEXPORT cmsSetProfileID(cmsHPROFILE hProfile, LPBYTE ProfileID)
       
   546 {
       
   547     LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
       
   548     CopyMemory(Icc -> ProfileID, ProfileID, 16);
       
   549 }
       
   550 
       
   551 
       
   552 BOOL LCMSEXPORT cmsTakeCreationDateTime(struct tm *Dest, cmsHPROFILE hProfile)
       
   553 {
       
   554     LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
       
   555     CopyMemory(Dest, &Icc ->Created, sizeof(struct tm));
       
   556     return TRUE;
       
   557 }
       
   558 
       
   559 
       
   560 icColorSpaceSignature LCMSEXPORT cmsGetPCS(cmsHPROFILE hProfile)
       
   561 {
       
   562        LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
       
   563        return Icc -> PCS;
       
   564 }
       
   565 
       
   566 
       
   567 void LCMSEXPORT cmsSetPCS(cmsHPROFILE hProfile, icColorSpaceSignature pcs)
       
   568 {
       
   569        LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
       
   570        Icc -> PCS = pcs;
       
   571 }
       
   572 
       
   573 
       
   574 
       
   575 icColorSpaceSignature LCMSEXPORT cmsGetColorSpace(cmsHPROFILE hProfile)
       
   576 {
       
   577        LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
       
   578        return Icc -> ColorSpace;
       
   579 }
       
   580 
       
   581 
       
   582 
       
   583 void LCMSEXPORT cmsSetColorSpace(cmsHPROFILE hProfile, icColorSpaceSignature sig)
       
   584 {
       
   585        LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
       
   586        Icc -> ColorSpace = sig;
       
   587 }
       
   588 
       
   589 
       
   590 icProfileClassSignature LCMSEXPORT cmsGetDeviceClass(cmsHPROFILE hProfile)
       
   591 {
       
   592        LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
       
   593        return Icc -> DeviceClass;
       
   594 }
       
   595 
       
   596 DWORD LCMSEXPORT cmsGetProfileICCversion(cmsHPROFILE hProfile)
       
   597 {
       
   598        LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
       
   599        return (DWORD) Icc -> Version;
       
   600 }
       
   601 
       
   602 
       
   603 void LCMSEXPORT cmsSetProfileICCversion(cmsHPROFILE hProfile, DWORD Version)
       
   604 {
       
   605    LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
       
   606    Icc -> Version = Version;
       
   607 }
       
   608 
       
   609 
       
   610 void LCMSEXPORT cmsSetDeviceClass(cmsHPROFILE hProfile, icProfileClassSignature sig)
       
   611 {
       
   612        LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
       
   613        Icc -> DeviceClass = sig;
       
   614 }
       
   615 
       
   616 
       
   617 // --------------------------------------------------------------------------------------------------------------
       
   618 
       
   619 
       
   620 static
       
   621 int SizeOfGammaTab(LPGAMMATABLE In)
       
   622 {
       
   623        return sizeof(GAMMATABLE) + (In -> nEntries - 1)*sizeof(WORD);
       
   624 }
       
   625 
       
   626 
       
   627 // Creates a phantom tag holding a memory block
       
   628 
       
   629 static
       
   630 LPVOID DupBlock(LPLCMSICCPROFILE Icc, LPVOID Block, size_t size)
       
   631 {
       
   632     if (Block != NULL && size > 0)
       
   633         return _cmsInitTag(Icc, (icTagSignature) 0, size, Block);
       
   634     else
       
   635         return NULL;
       
   636 
       
   637 }
       
   638 
       
   639 // This is tricky, since LUT structs does have pointers
       
   640 
       
   641 BOOL LCMSEXPORT _cmsAddLUTTag(cmsHPROFILE hProfile, icTagSignature sig, const void* lut)
       
   642 {
       
   643        LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
       
   644        LPLUT Orig, Stored;
       
   645        unsigned int i;
       
   646 
       
   647        // The struct itself
       
   648 
       
   649        Orig   = (LPLUT) lut;
       
   650        Stored = (LPLUT) _cmsInitTag(Icc, (icTagSignature) sig, sizeof(LUT), lut);
       
   651 
       
   652        // dup' the memory blocks
       
   653        for (i=0; i < Orig ->InputChan; i++)
       
   654             Stored -> L1[i] = (LPWORD) DupBlock(Icc, (LPWORD) Orig ->L1[i],
       
   655                                             sizeof(WORD) * Orig ->In16params.nSamples);
       
   656 
       
   657        for (i=0; i < Orig ->OutputChan; i++)
       
   658             Stored -> L2[i] = (LPWORD) DupBlock(Icc, (LPWORD) Orig ->L2[i],
       
   659                                             sizeof(WORD) * Orig ->Out16params.nSamples);
       
   660 
       
   661        Stored -> T     = (LPWORD) DupBlock(Icc, (LPWORD) Orig ->T, Orig -> Tsize);
       
   662 
       
   663        // Zero any additional pointer
       
   664        Stored ->CLut16params.p8 = NULL;
       
   665        return TRUE;
       
   666 }
       
   667 
       
   668 
       
   669 BOOL LCMSEXPORT _cmsAddXYZTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* XYZ)
       
   670 {
       
   671        LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
       
   672 
       
   673        _cmsInitTag(Icc, sig, sizeof(cmsCIEXYZ), XYZ);
       
   674        return TRUE;
       
   675 }
       
   676 
       
   677 
       
   678 BOOL LCMSEXPORT _cmsAddTextTag(cmsHPROFILE hProfile, icTagSignature sig, const char* Text)
       
   679 {
       
   680        LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
       
   681 
       
   682        _cmsInitTag(Icc, sig, strlen(Text)+1, (LPVOID) Text);
       
   683        return TRUE;
       
   684 }
       
   685 
       
   686 BOOL LCMSEXPORT _cmsAddGammaTag(cmsHPROFILE hProfile, icTagSignature sig, LPGAMMATABLE TransferFunction)
       
   687 {
       
   688     LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
       
   689 
       
   690     _cmsInitTag(Icc, sig, SizeOfGammaTab(TransferFunction), TransferFunction);
       
   691     return TRUE;
       
   692 }
       
   693 
       
   694 
       
   695 BOOL LCMSEXPORT _cmsAddChromaticityTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIExyYTRIPLE Chrm)
       
   696 {
       
   697     LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
       
   698 
       
   699     _cmsInitTag(Icc, sig, sizeof(cmsCIExyYTRIPLE), Chrm);
       
   700     return TRUE;
       
   701 }
       
   702 
       
   703 
       
   704 BOOL LCMSEXPORT _cmsAddSequenceDescriptionTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsSEQ pseq)
       
   705 {
       
   706     LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
       
   707 
       
   708     _cmsInitTag(Icc, sig, sizeof(int) + pseq -> n * sizeof(cmsPSEQDESC), pseq);
       
   709     return TRUE;
       
   710 
       
   711 }
       
   712 
       
   713 
       
   714 BOOL LCMSEXPORT _cmsAddNamedColorTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc)
       
   715 {
       
   716     LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
       
   717 
       
   718     _cmsInitTag(Icc, sig, sizeof(cmsNAMEDCOLORLIST) + (nc ->nColors - 1) * sizeof(cmsNAMEDCOLOR), nc);
       
   719     return FALSE;
       
   720 }
       
   721 
       
   722 
       
   723 BOOL LCMSEXPORT _cmsAddDateTimeTag(cmsHPROFILE hProfile, icTagSignature sig, struct tm *DateTime)
       
   724 {
       
   725     LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
       
   726 
       
   727     _cmsInitTag(Icc, sig, sizeof(struct tm), DateTime);
       
   728     return FALSE;
       
   729 }
       
   730 
       
   731 
       
   732 BOOL LCMSEXPORT _cmsAddColorantTableTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc)
       
   733 {
       
   734     LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
       
   735 
       
   736     _cmsInitTag(Icc, sig, sizeof(cmsNAMEDCOLORLIST) + (nc ->nColors - 1) * sizeof(cmsNAMEDCOLOR), nc);
       
   737     return FALSE;
       
   738 }