void PSDHelper::ReadResolution(StorageDevice* pFile) { DWORD dwDataSize; if (SeekImageResource(pFile, 0x03ED, dwDataSize) == ERRORCODE_None) { ASSERT(dwDataSize == sizeof(PSDResolutionInfo)); if (dwDataSize == sizeof(PSDResolutionInfo)) { PSDResolutionInfo Info; if (pFile->read(&Info, sizeof(Info)) == ERRORCODE_None) { // Extract the resolution. swap_dword((DWORD*)&Info.m_dwHRes); graphic->record.x_resolution = FixedInteger(Info.m_dwHRes); swap_dword((DWORD*)&Info.m_dwVRes); graphic->record.y_resolution = FixedInteger(Info.m_dwVRes); TRACE("Got PSD resolution %d x %d\n", graphic->record.x_resolution, graphic->record.y_resolution); } } } }
ERRORCODE PSDHelper::SeekImageResource(StorageDevice* pFile, WORD wSearchID, DWORD& dwDataSize) { ERRORCODE error; // Seek to the start of the image resources section. ST_DEV_POSITION lPos = m_Record.m_lImageResourcesSection; ST_DEV_POSITION lEnd = m_Record.m_lLayerMaskSection-4; // Swap the word to look for. This is better than swapping everything else. swap_word(&wSearchID); while (lPos < lEnd) { // Seek to the current resource. if ((error = pFile->seek(lPos, ST_DEV_SEEK_SET)) != ERRORCODE_None) { break; } DWORD dwType; WORD wID; CString csName; if ((error = pFile->read(&dwType, sizeof(dwType))) != ERRORCODE_None || (error = pFile->read(&wID, sizeof(wID))) != ERRORCODE_None || (error = ReadPString(pFile, csName)) != ERRORCODE_None || (error = pFile->read(&dwDataSize, sizeof(dwDataSize))) != ERRORCODE_None) { // Got an error. Break out now. break; } swap_dword(&dwDataSize); // We have the data. See if it's the one we're looking for. if (wID == wSearchID) { // Found it! break; } pFile->tell(&lPos); lPos += dwDataSize; if (dwDataSize & 1) { lPos++; } } return (lPos >= lEnd) ? ERRORCODE_DoesNotExist : error; }
int MTMiniConfig::savetostream(MTFile *f,int flags) { int l; unsigned int ikey[4]; MP *cp; if (flags & MTMC_HEADER) f->write("MTMC",4); if (flags & MTMC_STRUCTURE) f->write(&mp->nitems,4); l = 8; mp->reset(); while ((cp = (MP*)mp->next())){ if (flags & MTMC_STRUCTURE){ if (flags & MTMC_MD5KEYS){ md5b((unsigned char*)ikey,cp->key); l += f->write(ikey,sizeof(ikey)); } else{ l += f->write(cp->key,strlen(cp->key)+1); }; l += f->write(&cp->type,sizeof(cp->type)); }; if (((flags & MTMC_STRUCTURE) && (cp->type!=MTCT_BINARY)) || ((flags & MTMC_DATA) && (cp->type==MTCT_BINARY))) l += f->write(&cp->size,sizeof(cp->size)); if (flags & MTMC_DATA){ if (cp->type==MTCT_CONFIG){ l += ((MTMiniConfig*)cp->value)->savetostream(f,flags); } else if ((cp->type==MTCT_STRING) || (cp->type==MTCT_BINARY) || ((cp->type==MTCT_FLOAT) && (cp->size>4))){ l += f->write(cp->value,cp->size); } else{ # if (BIG_ENDIAN==1234) int _tmp = swap_dword(*(int*)cp->value); l += f->write(&_tmp,cp->size); # else l += f->write(&cp->value,cp->size); # endif }; }; }; return l; }
int MTMiniConfig::loadfromstream(MTFile *f,int flags) { int l,x; char id[5]; MP *cp,*ep; unsigned int ikey[4]; char key[256]; if (flags & MTMC_HEADER){ if (f->read(&id,4)!=4) return -1; id[5] = 0; if (strcmp(id,"MTMC")!=0) return -1; }; if (flags & MTMC_STRUCTURE){ if (f->read(&np,4)!=4) return -1; }; l = 0; cp = mtnew(MP); for (x=0;x<np;x++){ if (flags & MTMC_STRUCTURE){ if (flags & MTMC_MD5KEYS){ l += f->read(&ikey,sizeof(ikey)); ikey[0] = ((ikey[0]^ikey[1])^ikey[2])^ikey[3]; } else{ l += f->readln(key,256); key[255] = 0; cp->key = (char*)mtmemalloc(strlen(key)+1); strcpy(cp->key,key); }; l += f->read(&cp->type,sizeof(cp->type)); }; if (((flags & MTMC_STRUCTURE) && (cp->type!=MTCT_BINARY)) || ((flags & MTMC_DATA) && (cp->type==MTCT_BINARY))) l += f->read(&cp->size,sizeof(cp->size)); if (flags & MTMC_DATA){ if (cp->type==MTCT_CONFIG){ ((MTMiniConfig*)cp->value)->loadfromstream(f,flags); } else if ((cp->type==MTCT_STRING) || (cp->type==MTCT_BINARY) || ((cp->type==MTCT_FLOAT) && (cp->size>4))){ cp->value = mtmemalloc(cp->size); l += f->read(cp->value,cp->size); } else{ l += f->read(&cp->value,cp->size); # if (BIG_ENDIAN==1234) *(int*)cp->value = swap_dword(*(int*)cp->value); # endif }; }; ep = (MP*)(((flags & MTMC_STRUCTURE)==0)?mp->getitemfromid(x):((flags & MTMC_MD5KEYS)?mp->getitem(ikey[0]):mp->getitem(key))); if (ep){ if (ep->size==0) ep->size = cp->size; ep->value = cp->value; mtmemfree(cp); } else{ if (flags & MTMC_MD5KEYS) mp->additem(ikey[0],cp); else mp->additem(key,cp); }; }; return l; }
ERRORCODE PSDHelper::init(GRAPHIC_CREATE_STRUCT_PTR gcs) { ERRORCODE error = ERRORCODE_None; /* We need a file to read. */ StorageDevicePtr pSource; ReadOnlyFile file; if (gcs == NULL || (pSource = gcs->pSourceDevice) == NULL) { /* Go directly to disk. */ file.set_name(graphic->m_csFileName); file.set_read_buffer(4096); pSource = &file; } /* Read the header. */ PSDHeader Header; TRY { if ((error = pSource->read(&Header, sizeof(Header))) != ERRORCODE_None) { ThrowErrorcodeException(error); } // Swap everything. swap_word(&Header.m_wChannels); swap_dword(&Header.m_dwRows); swap_dword(&Header.m_dwColumns); swap_word(&Header.m_wDepth); swap_word(&Header.m_wMode); // Validate that we support this number of channels. if (Header.m_wChannels > MAX_CHANNELS) { ThrowErrorcodeException(ERRORCODE_IllegalType); } // Fill out the header. graphic->record.x_size = (USHORT)Header.m_dwColumns; graphic->record.y_size = (USHORT)Header.m_dwRows; graphic->record.x_resolution = 200; // Default for now... graphic->record.y_resolution = 200; // ...read later graphic->record.storage = GRAPHIC_STORAGE_FILE; // Fill out our info. m_Record.m_wChannels = Header.m_wChannels; m_Record.m_wDepth = Header.m_wDepth; m_Record.m_wMode = Header.m_wMode; // Initialize the start of line variables. #if 0 for (int i = 0; i < 9; i++) { m_Record.m_Lines[i].line = MulDiv((int)Header.m_dwRows, i, 8); m_Record.m_Lines[i].offset = 0L; } #endif DWORD dwSize; // // Process the color mode data section. // // Read the section size. if ((error = pSource->read(&dwSize, sizeof(dwSize))) != ERRORCODE_None) { ThrowErrorcodeException(error); } swap_dword(&dwSize); pSource->tell(&m_Record.m_lColorDataSection); // Skip to the next section. pSource->seek(m_Record.m_lColorDataSection + (ST_DEV_POSITION)dwSize, ST_DEV_SEEK_SET); // // Process the image resources section. // // Read the section size. if ((error = pSource->read(&dwSize, sizeof(dwSize))) != ERRORCODE_None) { ThrowErrorcodeException(error); } swap_dword(&dwSize); pSource->tell(&m_Record.m_lImageResourcesSection); // Skip to the next section. pSource->seek(m_Record.m_lImageResourcesSection + (ST_DEV_POSITION)dwSize, ST_DEV_SEEK_SET); // // Process the layer and mask section. // // Read the section size. if ((error = pSource->read(&dwSize, sizeof(dwSize))) != ERRORCODE_None) { ThrowErrorcodeException(error); } swap_dword(&dwSize); pSource->tell(&m_Record.m_lLayerMaskSection); // // Read the image resources we care about. // // Read the resolution information. ReadResolution(pSource); // Skip to the next section. pSource->seek(m_Record.m_lLayerMaskSection + (ST_DEV_POSITION)dwSize, ST_DEV_SEEK_SET); // // Process the image data section. // pSource->tell(&m_Record.m_lImageDataSection); // Read the compression value. if ((error = pSource->read(&m_Record.m_wCompression, sizeof(m_Record.m_wCompression))) != ERRORCODE_None) { ThrowErrorcodeException(error); } // // Compute the sizes of all data channels. // if (m_Record.m_wCompression) { // // Compression requires special handling. // // We are compressed; read the compression counts. LPWORD pCounts = NULL; // Needs to be NULL at start. if ((error = ReadCompressionCounts(pSource, pCounts)) != ERRORCODE_None) { ThrowErrorcodeException(error); } // Run through all channels and compute compressed sizes. LPWORD p = pCounts; int nRows = graphic->record.y_size; for (WORD wChannel = 0; wChannel < m_Record.m_wChannels; wChannel++) { // Compute the size of this channel. long lChannelSize = 0; for (int nRow = 0; nRow < nRows; nRow++) { lChannelSize += *p++; } // Save the channel size in the record. m_Record.m_lChannelSizes[wChannel] = lChannelSize; } // Free the count data. GlobalFreePtr(pCounts); } else { // // Not compressed. All channels are the same size. // DWORD dwChannelSize = Header.m_dwColumns * Header.m_dwRows; // Set them all to the same size. for (WORD wChannel = 0; wChannel < m_Record.m_wChannels; wChannel++) { m_Record.m_lChannelSizes[wChannel] = (long)dwChannelSize; } } } CATCH(CErrorcodeException, e) { error = e->m_error; } AND_CATCH_ALL(e) { error = ERRORCODE_IntError; } END_CATCH_ALL return error; }