void ZDCPixmapDecoder_GIF::Imp_Read(const ZStreamR& iStream, ZDCPixmap& oPixmap) { oPixmap = ZDCPixmap(); if (fReadEnd) return; if (!fReadHeader) { fReadHeader = true; if ('G' != iStream.ReadUInt8() || 'I' != iStream.ReadUInt8() || 'F' != iStream.ReadUInt8() || '8' != iStream.ReadUInt8()) { sThrowBadFormat(); } uint8 version = iStream.ReadUInt8(); if ('7' != version && '9' != version) sThrowBadFormat(); if ('a' != iStream.ReadUInt8()) sThrowBadFormat(); fIs89a = version == '9'; fSize.h = iStream.ReadUInt16LE(); fSize.v = iStream.ReadUInt16LE(); uint8 strmFlags = iStream.ReadUInt8(); bool strmHasGlobalColorTable = (strmFlags & 0x80) != 0; uint8 strmColorResolution = (strmFlags & 0x7) >> 4; bool strmSortFlag = (strmFlags & 0x08) != 0; uint8 strmGlobalColorTableSize = (strmFlags & 0x7); uint8 strmBackgroundColorIndex = iStream.ReadUInt8(); uint8 strmPixelAspectRatio = iStream.ReadUInt8(); if (strmHasGlobalColorTable) { vector<ZRGBColorPOD> theColors; sReadColorTable(iStream, 1 << (strmGlobalColorTableSize + 1), theColors); fPixelDesc = ZDCPixmapNS::PixelDesc(&theColors[0], theColors.size()); } static int sPhysicalDepths[] = { 1, // 0 2, // 1 4, // 2 4, // 3 8, // 4 8, // 5 8, // 6 8, // 7 }; int rowBytes = ZDCPixmapNS::sCalcRowBytes(sPhysicalDepths[strmGlobalColorTableSize], fSize.h); ZDCPixmapNS::RasterDesc theRasterDesc( ZDCPixmapNS::PixvalDesc(strmGlobalColorTableSize + 1, true), rowBytes, fSize.v, false); fRaster = new ZDCPixmapRaster_Simple(theRasterDesc); fRaster->Fill(strmBackgroundColorIndex); }
void ZDCPixmapDecoder_GIF::Imp_Read(const ZStreamR& iStream, ZDCPixmap& oPixmap) { oPixmap = ZDCPixmap(); if (fReadEnd) return; if (!fReadHeader) { fReadHeader = true; if ('G' != iStream.ReadUInt8() || 'I' != iStream.ReadUInt8() || 'F' != iStream.ReadUInt8() || '8' != iStream.ReadUInt8()) { spThrowBadFormat(); } uint8 version = iStream.ReadUInt8(); if ('7' != version && '9' != version) spThrowBadFormat(); if ('a' != iStream.ReadUInt8()) spThrowBadFormat(); fIs89a = version == '9'; fSize.h = iStream.ReadUInt16LE(); fSize.v = iStream.ReadUInt16LE(); uint8 strmFlags = iStream.ReadUInt8(); bool strmHasGlobalColorTable = (strmFlags & 0x80) != 0; //uint8 strmColorResolution = (strmFlags & 0x7) >> 4; //bool strmSortFlag = (strmFlags & 0x08) != 0; uint8 strmGlobalColorTableSize = (strmFlags & 0x7); uint8 strmBackgroundColorIndex = iStream.ReadUInt8(); /*uint8 strmPixelAspectRatio = */iStream.ReadUInt8(); if (strmHasGlobalColorTable) { vector<ZRGBA_POD> theColors; spReadColorTable(iStream, 1 << (strmGlobalColorTableSize + 1), theColors); fPixelDesc = PixelDesc(&theColors[0], theColors.size()); } static int sPhysicalDepths[] = { 1, // 0 2, // 1 4, // 2 4, // 3 8, // 4 8, // 5 8, // 6 8, // 7 }; int rowBytes = sCalcRowBytes(sPhysicalDepths[strmGlobalColorTableSize], fSize.h, 4); RasterDesc theRasterDesc( PixvalDesc(strmGlobalColorTableSize + 1, true), rowBytes, fSize.v, false); fRaster = new ZDCPixmapRaster_Simple(theRasterDesc); fRaster->Fill(strmBackgroundColorIndex); } else { // Clone our existing raster which contains the pixels // making up the pixmap we last returned. fRaster = new ZDCPixmapRaster_Simple(fRaster); } for (;;) { uint8 blockType = iStream.ReadUInt8(); if (blockType == ';') { // We've reached the end of the GIF stream. fReadEnd = true; return; } else if (blockType == '!') { // It's an extension. // Ignore the extension type iStream.ReadUInt8(); // Skip any data blocks. StreamR_Chunk(iStream).SkipAll(); } else if (blockType == ',') { // It's an image. ZRectPOD curBounds; curBounds.left = iStream.ReadUInt16LE(); curBounds.top = iStream.ReadUInt16LE(); curBounds.right = curBounds.left + iStream.ReadUInt16LE(); curBounds.bottom = curBounds.top + iStream.ReadUInt16LE(); uint8 strmFlags = iStream.ReadUInt8(); bool strmHasLocalColorTable = (strmFlags & 0x80) != 0; bool strmIsInterlaced = (strmFlags & 0x40) != 0; //bool strmSortFlag = (strmFlags & 0x20) != 0; uint8 strmLocalColorTableSize = (strmFlags & 0x7); PixelDesc thePixelDesc = fPixelDesc; if (strmHasLocalColorTable) { vector<ZRGBA_POD> theColors; spReadColorTable(iStream, 1 << (strmLocalColorTableSize + 1), theColors); thePixelDesc = PixelDesc(&theColors[0], theColors.size()); } spReadImageData(iStream, strmIsInterlaced, curBounds, fRaster); oPixmap = new ZDCPixmapRep(fRaster, sRect(fSize), thePixelDesc); return; } } }