Zhing
PSD format file reading
| | |
Photoshop, I don't want people, I don't know. The latest version is 6.0, and its image file * .psd and 5.5 are not very big. I will introduce the reading method of the * .psd file and provide a complete read function. Where: m_rect is the target area, m_lpdds7 is the target DirectDraw surface, M_PBALPhamask is the target APLHA advertisement pointer. The READ16 function reads a Word from the current location of the specified file, the READ32 function reads a DWORD from the current location of the specified file. MAX_PSD_CHANNELS is 24. The following is the reading method of * .psd file, interested friends can continue to study, but don't forget to send me one.
HRESULT LoadPSD (LPSTR strFilename) // read the PSD file {DWORD dwWidth, dwHeight; // Width High long lSurfWidth = m_Rect.right - m_Rect.left; long lSurfHeight = m_Rect.bottom - m_Rect.top; WORD CompressionType; // compression Type HDC HDC; File * fppsd; Word channel; // Open PSD file IF ((fppsd = fopen (strfilename, "rb")) == null) {Return E_FAIL;} // First four bytes For "8bps" char signature [5]; signature [0] = fgetc (fPPSD); Signature [1] = fgetc (fPPSD); Signature [2] = fgetc (fppsd); Signature [3] = FGETC (FPPSD); Signature [4] = '/ 0'; if (STRCMP (Signature, "8bps")! = 0) {RETURN E_FAIL;} // version must be 1 IF (READ16 (FPPSD)! = 1) {RETURN E_FAIL;} // Skip some data (always 0) Read32 (FPPSD); Read16 (FPPSD); // Read the channel number channelcount = read16 (fppsd); // Determine at least one channel IF ((ChannelCount <0) || (CHANNELCOUNT> MAX_PSD_CHANNELS)) {Return E_FAIL;} // Read Wide and High DwHeight = Read32 (FPPSD); dwwidth = = = = = read32 (FPP SD); if (dwwidth! = (DWord) lsurfwidth || dwheight! = (Dword) lsurfheight) {return e_fail;} // Read only 8-bit channel IF (READ16 (FPPSD)! = 8) {Return E_FAIL;} // Determine the mode to RGB. // Possio value: // 0: Bit map // 1: grayshade // 2: Index // 3: RGB // 4: CMYK // 8: Duotone / / 9: Lab if (READ16 (FPPSD)! = 3) {RETURN E_FAIL;} // Skip data (such as palette) int modedatacount = read32 (fppsd); if (modiTacount) fseek (fppsd, modedatacount, seek_cur) ; // Skip data (such as Pen Tool Paths, etc) int resourceDataCount =
Read32 (fpPSD); if (ResourceDataCount) fseek (fpPSD, ResourceDataCount, SEEK_CUR); // data pieces had retained int ReservedDataCount = Read32 (fpPSD); if (ReservedDataCount) fseek (fpPSD, ReservedDataCount, SEEK_CUR); // 0: Non- Compressed // 1: RLE compression compressionType = read16 (fPPSD); if (compressionType> 1) {RETURN E_FAIL;} Byte * psdpixels = new byte [(lsurfwidth * lsurfheight) * 4]; // Unpack data unpackpsd (fppsd, lSurfWidth, lSurfHeight, PSDPixels, ChannelCount, CompressionType); fclose (fpPSD); // copy information BITMAPINFO BitmapInfo; ZeroMemory (& BitmapInfo, sizeof (BitmapInfo)); BitmapInfo.bmiHeader.biSize = sizeof (BitmapInfo.bmiHeader); BitmapInfo.bmiHeader. biWidth = lSurfWidth; BitmapInfo.bmiHeader.biHeight = -lSurfHeight; BitmapInfo.bmiHeader.biPlanes = 1; BitmapInfo.bmiHeader.biBitCount = 32; m_lpDDS7-> GetDC (& hDC); int rc = StretchDIBits (hDC, 0, 0, lSurfWidth,lSurfHeight, 0, 0, lSurfWidth, lSurfHeight, PSDPixels, & BitmapInfo, DIB_RGB_COLORS, SRCCOPY); m_lpDDS7-> ReleaseDC (hDC); if (rc == GDI_ERROR) {H_ARRAY_DELETE (PSDPixels); #ifdef _DEBUG g_pHERR-> OutDebugMsg (3, H2DSERR_INVALID_PSD); #endif return E_FAIL;} // whether to read Alpha mixing channel if (ChannelCount> 3) {m_pbAlphaMask = new BYTE [lSurfWidth * lSurfHeight]; for (int x = 0; x ) {M_pbalphamask [(Y * lsurfwidth) x] = psdpixels [(Y * lsurfheight) x) * 4) 3];}} else {m_pbalphamask = null;} h_array_delete (psdpixels); return dd_ok;} // PSD file unpacking vid chades2dsurface :: unpades2dsd (file * fp, // fp is PSD file pointer, dword dwidth, // dwordth, dwheight is high, DWORD dwheight, byte * pixels, // pixels is unpacking target Pointer, Word Channelcnt, // CHANNELCNT is the number of channels, Word Compression // Compression bit compression type. {Int default [4] = {0, 0, 0, 255}; int CHN [4] = {2, 1, 0, 3}; int Pixelcount = dwwidth * dwheight; if (compression) {FSeek (FP, Dwheight * Channel * 2, seek_cur); for (int C = 0; c <4; c ) {int PN = 0; int channel = chn [c]; if (channel> = channel) {for (pn = 0; PN ELSE IF (Len <128) // Non-RLE