LPPALETTE ReadPalette( LPSTR lpFileName, BOOL bCombine ) /************************************************************************/ { int ifh; /* file handle( unbuffered) */ FILEBUF ifd; /* file descriptor( buffered) */ short i, iColors; VERSIONINFO version; RECINFO rec; LPTR lpByte; LPWORD lpWord; LPLONG lpLong; BYTE Previous; BOOL bError; FNAME szName; LPPALETTE lpHeadPalette, lpPalette, lpBigPalette; /* open the palette file */ if ( ( ifh = _lopen( lpFileName, OF_READ)) < 0 ) { Message( IDS_EOPEN, lpFileName); return( NULL ); } /* create a buffered stream to speed access */ FileFDOpenRdr( &ifd, ifh, (LPTR)LineBuffer[0], 16*1024); // read palette version version.Length = sizeof(version.Number); version.Type = PALFILE_VERSION; FileRead(&ifd, (LPTR)&version, sizeof(version)); #ifdef _MAC swapw(&version.Length); swapw(&version.Number); #endif if (ifd.err || version.Type != PALFILE_VERSION || version.Length != sizeof(version.Number) || version.Number > CURRENT_VERSION) { Message(IDS_INVALIDPALETTE, lpFileName); _lclose(ifh); return(NULL); } rec.Type = 0; lpHeadPalette = NULL; lpPalette = NULL; bError = NO; while (!bError && !ifd.err && rec.Type != PALFILE_END) { Previous = rec.Type; FileRead(&ifd, (LPTR)&rec, sizeof(RECINFO)); #ifdef _MAC swapw(&rec.Length); #endif if (ifd.err) break; switch (rec.Type) { case PALFILE_VERSION: bError = YES; break; case PALFILE_COUNT: lpByte = Alloc((long)rec.Length); FileRead(&ifd, lpByte, rec.Length); FreeUp(lpByte); break; case PALFILE_COLORS: if (!lpPalette) { bError = YES; break; } lpWord = (LPWORD)Alloc((long)rec.Length); if (!lpWord) { Message (IDS_EMEMALLOC); bError = YES; break; } FileRead(&ifd, (LPTR)lpWord, rec.Length); if (ifd.err) { FreeUp((LPTR)lpWord); break; } #ifdef _MAC swapw(lpWord); #endif iColors = *lpWord; if ((iColors * sizeof(COLOR) + sizeof(WORD)) != rec.Length) { FreeUp((LPTR)lpWord); bError = YES; break; } lpPalette->iColors = iColors; if (!iColors) { FreeUp((LPTR)lpWord); break; } lpLong = (LPLONG)(lpWord+1); lpPalette->lpColorInfo = (LPCOLORINFO)Alloc((long)(sizeof(COLORINFO)*iColors)); if (!lpPalette->lpColorInfo) { Message(IDS_EMEMALLOC); FreeUp((LPTR)lpWord); bError = YES; break; } for (i = 0; i < iColors; ++i) { LPVOID lp = &lpPalette->lpColorInfo[i].rgb; #ifdef _MAC swapl((LPDWORD)lp); #endif CopyRGB(lpLong+i, lp); SetColorInfo( &lpPalette->lpColorInfo[i], &lpPalette->lpColorInfo[i], CS_RGB); } FreeUp((LPTR)lpWord); break; case PALFILE_NAME: if (Previous == PALFILE_NAME) { bError = YES; break; } if (lpPalette) { lpHeadPalette = LinkPalette(lpHeadPalette, lpPalette); lpPalette = NULL; } rec.Length = bound(rec.Length, 0, MAX_FNAME_LEN); FileRead(&ifd, (LPTR)szName, rec.Length); if (ifd.err) break; lpPalette = NewPalette(szName); if (!lpPalette) { Message (IDS_EMEMALLOC); bError = YES; break; } break; case PALFILE_GROUP: if (!lpPalette || (rec.Length != sizeof(lpPalette->dwGroup))) { bError = YES; break; } FileRead(&ifd, (LPTR)&lpPalette->dwGroup, rec.Length); #ifdef _MAC swapl((LPDWORD)(&lpPalette->dwGroup)); #endif break; case PALFILE_LABELS: if (!lpPalette) { bError = YES; break; } lpPalette->lpLabels = Alloc((long)rec.Length); if (!lpPalette->lpLabels) { Message (IDS_EMEMALLOC); bError = YES; break; } lpPalette->LabelsLength = rec.Length; FileRead(&ifd, lpPalette->lpLabels, rec.Length); break; case PALFILE_FORMAT: if (!lpPalette || (rec.Length > MAX_STR_LEN)) { bError = YES; break; } FileRead(&ifd, (LPTR)lpPalette->szFormat, rec.Length); break; case PALFILE_END: if (lpPalette) { lpHeadPalette = LinkPalette(lpHeadPalette, lpPalette); lpPalette = NULL; } break; default: bError = YES; break; } } _lclose(ifh); if (lpPalette) { if (lpPalette->lpColorInfo) FreeUp((LPTR)lpPalette->lpColorInfo); if (lpPalette->lpLabels) FreeUp((LPTR)lpPalette->lpLabels); FreeUp((LPTR)lpPalette); } if (ifd.err || bError || rec.Type != PALFILE_END || lpPalette) { Message(IDS_INVALIDPALETTE, lpFileName); FreeUpPalette(lpHeadPalette); return(NULL); } if ( !bCombine || !lpHeadPalette ) return( lpHeadPalette ); if ( !(lpBigPalette = CombinePalettes(lpHeadPalette)) ) Message (IDS_EMEMALLOC); FreeUpPalette(lpHeadPalette); return( lpBigPalette ); }
BOOL CReadBitmap::GIFRead() /************************************************************************/ { GIFHDR hdr; GIFDESC ImDesc; GIFMAP GlobalMap; GIFMAP LocalMap; BYTE cTemp; LPTR lpFileLine, lpLineBuffer, lpOut; LPFRAME lpFrame; FILEBUF ifd; /* file descriptor (buffered) */ BOOL graymap; int i; int sy; int xres; /* pixels per inch */ int npix; /* image width (pixels) */ int nlin; /* image height (pixels) */ BYTE codeSize; int iCodeSize; int iRowMapIndex; BOOL compressInit; LPLZW_STUFF lpLZW; FRMTYPEINFO inType, outType; LPCOLORMAP lpColorMap; CFrameTypeConvert TypeConvert; CFile theFile; CFile* pTheFile; BOOL fRet = FALSE; ProgressBegin(1); if ((pTheFile = OpenFile()) == NULL) { ProgressEnd(); return(FALSE); } TRY { lpFileLine = NULL; lpFrame = NULL; lpLineBuffer = NULL; compressInit = NO; lpColorMap = NULL; if (!(lpLineBuffer = Alloc (BUF_SIZE))) goto Exit; FileFDOpenRdr (&ifd, pTheFile, lpLineBuffer, BUF_SIZE); /* initialize the Global and local color maps */ gifInitColorMap (&GlobalMap); gifInitColorMap (&LocalMap); /* read gif file header */ if (gifReadHeader (&ifd, &hdr)) goto BadRead; /* get global color map, if any */ if (hdr.GlobalMap) { if (gifReadColorMap (&ifd, hdr.bpp, &GlobalMap)) goto BadRead; } /* look for start of image */ while (1) { FileFDRead (&ifd, (LPTR) &cTemp, 1); if (ifd.err) goto BadRead; /* test for image separator character */ if (cTemp == GIFImSep) break; /* test for terminator character (no image blocks in file?) */ if (cTemp == GIFImSep) goto BadRead; /* test for extension block character */ if (cTemp == GIFExtBlk) { /* Skip over the extension block */ /* read function code */ FileFDRead (&ifd, (LPTR) &cTemp, 1); do { /* read byte count */ FileFDRead (&ifd, (LPTR) &cTemp, 1); /* skip data bytes */ if (cTemp) FileFDSeek (&ifd, (long) cTemp, 1); } while (cTemp); } } /* now at the start of the first image */ if (gifReadImDesc (&ifd, &ImDesc)) goto BadRead; /* read local color map, if any */ if (ImDesc.LocalMap) { if (gifReadColorMap (&ifd, ImDesc.bpp, &LocalMap)) goto BadRead; } else { LocalMap = GlobalMap; ImDesc.bpp = hdr.bpp; } /* check for gray map */ graymap = TRUE; for (i = 0; (i < LocalMap.Length) && graymap; i++) graymap = (LocalMap.Map[i].red == LocalMap.Map[i].green) && (LocalMap.Map[i].red == LocalMap.Map[i].blue); lpColorMap = FrameCreateColorMap(); if (!lpColorMap) { SetError(BEC_errMemory); goto Exit; } lpColorMap->NumEntries = LocalMap.Length; for (i = 0; i < LocalMap.Length; ++i) lpColorMap->RGBData[i] = LocalMap.Map[i]; /* get width of image in pixels */ npix = ImDesc.ImWidth; nlin = ImDesc.ImHeight; xres = 75; if (hdr.bpp == 1) FrameSetTypeInfo(&inType, FDT_LINEART); else FrameSetTypeInfo(&inType, FDT_PALETTECOLOR, lpColorMap); if (!SetupTypes(&inType, &outType, graymap)) goto Exit; FrameSetTypeInfo(&inType, FDT_PALETTECOLOR, lpColorMap); if (!TypeConvert.Init(inType, outType, npix, m_DitherType)) { SetError(BEC_errMemory); goto Exit; } /* allocate space for one line of the image (file) */ if ( !AllocLines (&lpFileLine, 1, npix, 1)) { SetError(BEC_errMemory); goto BadWrite; } /* Create the image frame store */ lpFrame = FrameOpen(outType, npix, nlin, xres); if ( !lpFrame ) { SetError(BEC_errFrameOpen); goto Exit; } /* convert the image */ if (FileFDRead (&ifd, &codeSize, 1) == -1) goto BadRead; iCodeSize = codeSize; if (FileFDSeek (&ifd, 0L, 1) == -1) goto BadRead; if ( !( lpLZW = DecompressLZW_GIF (ifd.pFile, NULL, 0, iCodeSize, NULL))) goto BadRead; compressInit = YES; if (ImDesc.Interlaced) iRowMapIndex = 1; else iRowMapIndex = 0; sy = gifRowMap [iRowMapIndex].first; for (i = 0; i < nlin; i++) { if (Progress (i, nlin, YES)) goto Exit; if (!(DecompressLZW_GIF (ifd.pFile, lpFileLine, npix, iCodeSize, lpLZW))) goto BadRead; if ( !(lpOut = FramePointerRaw(lpFrame, 0, sy, YES)) ) goto BadWrite; TypeConvert.ConvertData(lpFileLine, lpOut, sy, npix); sy += gifRowMap [iRowMapIndex].step; if (sy >= ImDesc.ImHeight) { iRowMapIndex++; sy = gifRowMap [iRowMapIndex].first; } } m_iWidth = npix; m_iHeight = nlin; m_iRes = xres; m_lpFrame = lpFrame; fRet = TRUE; goto Exit; } CATCH_ALL(e) { goto BadRead; } END_CATCH_ALL ProgressEnd(); return (TRUE); BadRead: SetError(BEC_errFileRead); goto Exit; BadWrite: SetError(BEC_errFrameRead); Exit: if (compressInit) DecompressLZW_GIF (ifd.pFile, NULL, 0, iCodeSize, lpLZW); compressInit = NO; if ( lpFileLine ) FreeUp( lpFileLine ); if ( lpLineBuffer ) FreeUp (lpLineBuffer); if ( lpColorMap ) FrameDestroyColorMap(lpColorMap); CloseFile(pTheFile); if (!fRet && lpFrame) FrameClose(lpFrame); ProgressEnd(); return(fRet); }