LCMSBOOL _cmsModifyTagData(cmsHPROFILE hProfile, icTagSignature sig, void *data, size_t size) { LCMSBOOL isNew; int i, idx, delta, count; LPBYTE padChars[3] = {0, 0, 0}; LPBYTE beforeBuf, afterBuf, ptr; size_t beforeSize, afterSize; icUInt32Number profileSize, temp; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; isNew = FALSE; idx = _cmsSearchTag(Icc, sig, FALSE); if (idx < 0) { isNew = TRUE; idx = Icc->TagCount++; if (Icc->TagCount >= MAX_TABLE_TAG) { J2dRlsTraceLn1(J2D_TRACE_ERROR, "_cmsModifyTagData: Too many tags " "(%d)\n", Icc->TagCount); Icc->TagCount = MAX_TABLE_TAG-1; return FALSE; } } /* Read in size from header */ Icc->Seek(Icc, 0); Icc->Read(&profileSize, sizeof(icUInt32Number), 1, Icc); AdjustEndianess32((LPBYTE) &profileSize); /* Compute the change in profile size */ if (isNew) { delta = sizeof(icTag) + ALIGNLONG(size); } else { delta = ALIGNLONG(size) - ALIGNLONG(Icc->TagSizes[idx]); } /* Add tag to internal structures */ ptr = malloc(size); if (ptr == NULL) { if(isNew) { Icc->TagCount--; } J2dRlsTraceLn(J2D_TRACE_ERROR, "_cmsModifyTagData: ptr == NULL"); return FALSE; } /* We change the size of Icc here only if we know it'll actually * grow: if Icc is about to shrink we must wait until we've read * the previous data. */ if (delta > 0) { if (!Icc->Grow(Icc, delta)) { free(ptr); if(isNew) { Icc->TagCount--; } J2dRlsTraceLn(J2D_TRACE_ERROR, "_cmsModifyTagData: Icc->Grow() == FALSE"); return FALSE; } } /* Compute size of tag data before/after the modified tag */ beforeSize = ((isNew)?profileSize:Icc->TagOffsets[idx]) - Icc->TagOffsets[0]; if (Icc->TagCount == (idx + 1)) { afterSize = 0; } else { afterSize = profileSize - Icc->TagOffsets[idx+1]; } /* Make copies of the data before/after the modified tag */ if (beforeSize > 0) { beforeBuf = malloc(beforeSize); if (!beforeBuf) { if(isNew) { Icc->TagCount--; } free(ptr); J2dRlsTraceLn(J2D_TRACE_ERROR, "_cmsModifyTagData: beforeBuf == NULL"); return FALSE; } Icc->Seek(Icc, Icc->TagOffsets[0]); Icc->Read(beforeBuf, beforeSize, 1, Icc); } if (afterSize > 0) { afterBuf = malloc(afterSize); if (!afterBuf) { free(ptr); if(isNew) { Icc->TagCount--; } if (beforeSize > 0) { free(beforeBuf); } J2dRlsTraceLn(J2D_TRACE_ERROR, "_cmsModifyTagData: afterBuf == NULL"); return FALSE; } Icc->Seek(Icc, Icc->TagOffsets[idx+1]); Icc->Read(afterBuf, afterSize, 1, Icc); } CopyMemory(ptr, data, size); Icc->TagSizes[idx] = size; Icc->TagNames[idx] = sig; if (Icc->TagPtrs[idx]) { free(Icc->TagPtrs[idx]); } Icc->TagPtrs[idx] = ptr; if (isNew) { Icc->TagOffsets[idx] = profileSize; } /* Update the profile size in the header */ profileSize += delta; Icc->Seek(Icc, 0); temp = TransportValue32(profileSize); Icc->Write(Icc, sizeof(icUInt32Number), &temp); /* Shrink Icc, if needed. */ if (delta < 0) { if (!Icc->Grow(Icc, delta)) { free(ptr); if(isNew) { Icc->TagCount--; } J2dRlsTraceLn(J2D_TRACE_ERROR, "_cmsModifyTagData: Icc->Grow() == FALSE"); return FALSE; } } /* Adjust tag offsets: if the tag is new, we must account for the new tag table entry; otherwise, only those tags after the modified tag are changed (by delta) */ if (isNew) { for (i = 0; i < Icc->TagCount; ++i) { Icc->TagOffsets[i] += sizeof(icTag); } } else { for (i = idx+1; i < Icc->TagCount; ++i) { Icc->TagOffsets[i] += delta; } } /* Write out a new tag table */ count = 0; for (i = 0; i < Icc->TagCount; ++i) { if (Icc->TagNames[i] != 0) { ++count; } } Icc->Seek(Icc, sizeof(icHeader)); temp = TransportValue32(count); Icc->Write(Icc, sizeof(icUInt32Number), &temp); for (i = 0; i < Icc->TagCount; ++i) { if (Icc->TagNames[i] != 0) { icTag tag; tag.sig = TransportValue32(Icc->TagNames[i]); tag.offset = TransportValue32((icInt32Number) Icc->TagOffsets[i]); tag.size = TransportValue32((icInt32Number) Icc->TagSizes[i]); Icc->Write(Icc, sizeof(icTag), &tag); } } /* Write unchanged data before the modified tag */ if (beforeSize > 0) { Icc->Write(Icc, beforeSize, beforeBuf); free(beforeBuf); } /* Write modified tag data */ Icc->Write(Icc, size, data); if (size % 4) { Icc->Write(Icc, 4 - (size % 4), padChars); } /* Write unchanged data after the modified tag */ if (afterSize > 0) { Icc->Write(Icc, afterSize, afterBuf); free(afterBuf); } return TRUE; }
/************************************************** * * Create a Device Independent Bitmap... * * **************************************************/ void Create_DIB( HWND hWnd ) { HDC hDC; unsigned char i; long k,j; LPBITMAPINFO info; unsigned char *dat; hDC = GetDC (hWnd) ; // Intialize BITMAPINFOHEADER data. //................................. bi.biSize = sizeof (BITMAPINFOHEADER) ; bi.biWidth = W; bi.biHeight = H; bi.biPlanes = 1; bi.biBitCount = COLORBITS; bi.biCompression = BI_RGB; bi.biSizeImage = ( ALIGNLONG( (W * COLORBITS)/8 ) * H); bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 256; bi.biClrImportant = 256; // Allocate memory for BITMAPINFO structure. //.......................................... lpbi = (BITMAPINFOHEADER*)GlobalAlloc( GPTR, sizeof(BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD) + (ALIGNLONG((W * COLORBITS)/8) * H) ); // Copy BITMAPINFOHEADER information. //................................... *lpbi = bi; // Create The Palette info = (LPBITMAPINFO) lpbi; for ( i=0; i<255; i++ ) { info->bmiColors[i].rgbRed = i; info->bmiColors[i].rgbBlue = i; info->bmiColors[i].rgbGreen = i; info->bmiColors[i].rgbReserved = 0; } // Set pointer to bitmap’s bit data. //.................................. lpstBitmap = (LPSTR)lpbi + (WORD)sizeof(BITMAPINFOHEADER) + (256 * sizeof(RGBQUAD)); dat = lpstBitmap; for ( k=0; k< H; k++ ) for ( j = 0; j < W; j++ ) *dat++ = k; // Create uninitialized DIB bitmap. //................................. hBitmap = CreateDIBitmap( hDC, &bi, 0, lpstBitmap, (LPBITMAPINFO) lpbi, DIB_RGB_COLORS); ReleaseDC( hWnd, hDC); }