static bool sTryGIF(const ZStreamR& iStream) { if ('G' != iStream.ReadUInt8() || 'I' != iStream.ReadUInt8() || 'F' != iStream.ReadUInt8() || '8' != iStream.ReadUInt8()) { return false; } return true; }
static bool sTryBMP(const ZStreamR& iStream) { if (0x42 != iStream.ReadUInt8() || 0x4D != iStream.ReadUInt8()) { return false; } return true; }
static void sReadRLE8(const ZStreamR& iStream, ZCoord iWidth, ZCoord iHeight, size_t iRowBytes, bool iFlip, uint8* iBuffer) { ZCoord currentRow = 0; ZCoord currentCol = 0; bool done = false; while (!done) { uint8 count = iStream.ReadUInt8(); uint8 command = iStream.ReadUInt8(); if (count == 0) { switch (command) { case 0: // Move to start of next row { currentRow += 1; currentCol = 0; break; } case 1: // All done { done = true; break; } case 2: // Offset by some relative amount { currentCol += iStream.ReadUInt8(); currentRow += iStream.ReadUInt8(); break; } default: // Absolute data follows -- the length is the value of 'command' { uint8* destAddress = iBuffer + iRowBytes * (iFlip ? iHeight - currentRow - 1 : currentRow) + currentCol; iStream.Read(destAddress, command); currentCol += command; // An odd number of bytes is followed by a pad byte. if ((command & 1) != 0) iStream.Skip(1); break; } } } else { // Store a run of bytes. The count is in 'count', the value is in 'command'. uint8* destAddress = iBuffer + iRowBytes * (iFlip ? iHeight - currentRow - 1 : currentRow) + currentCol; for (int x = 0; x < count; ++x) *destAddress++ = command; currentCol += count; } } }
static bool sTryKF(const ZStreamR& iStream) { iStream.Skip(8); if ('P' != iStream.ReadUInt8() || 'N' != iStream.ReadUInt8() || 'T' != iStream.ReadUInt8() || 'R' != iStream.ReadUInt8()) { return false; } return true; }
static bool sTryPNG(const ZStreamR& iStream) { if (0x89 != iStream.ReadUInt8() || 0x50 != iStream.ReadUInt8() || 0x4E != iStream.ReadUInt8() || 0x47 != iStream.ReadUInt8() || 0x0D != iStream.ReadUInt8() || 0x0A != iStream.ReadUInt8() || 0x1A != iStream.ReadUInt8() || 0x0A != iStream.ReadUInt8()) { return false; } return true; }
static inline uint32 sReadCount(const ZStreamR& iStreamR) { uint8 firstByte = iStreamR.ReadUInt8(); if (firstByte < 0xFF) return firstByte; return iStreamR.ReadUInt32(); }
void NPainter_FromPICT(const ZStreamR& inStream, ZDCPixmap& outPixmap) { inStream.ReadInt16(); // picSize. This field has been obsolete since 1987. inStream.ReadInt16(); // picFrame.top inStream.ReadInt16(); // picFrame.left inStream.ReadInt16(); // picFrame.bottom inStream.ReadInt16(); // picFrame.right uint8 ch; // skip any empty bytes while ((ch = inStream.ReadUInt8()) == 0) {} if (ch != 0x11) throw runtime_error("NPainter_FromPICT, expected version opcode"); if ((ch = inStream.ReadUInt8()) != 0x02) throw runtime_error("NPainter_FromPICT, expected version number 2"); if ((ch = inStream.ReadUInt8()) != 0xFF) throw runtime_error("NPainter_FromPICT, expected subcode 0xFF"); // The order of remaining opcodes is not always the same, hence we use a loop to consume them. uint16 opcode; while (true) { opcode = inStream.ReadUInt16(); if (opcode == 0x0C00) // Header, followed by 24 bytes of data we don't need inStream.Skip(24); else if (opcode == 0x01) // Clip rgn { unsigned short clipBytes = inStream.ReadUInt16() - sizeof(short); inStream.Skip(clipBytes); } else if (opcode != 0x1E) // Hilite break; } if (opcode != 0x98) throw runtime_error("NPainter_FromPICT, expected packbits opcode"); // Do the actual read ::sReadPixmap(inStream, outPixmap); // Suck up remaining data while ((ch = inStream.ReadUInt8()) == 0x00) {} if (ch != 0xFF) throw runtime_error("NPainter_FromPICT, expected end of picture opcode"); }
static ZRef<ZTBQueryNode> sNodeFromStream(const ZStreamR& iStreamR) { uint8 theType = iStreamR.ReadUInt8(); switch (theType) { case 0: return ZRef<ZTBQueryNode>(); case 1: return new ZTBQueryNode_All(iStreamR); case 2: return new ZTBQueryNode_Combo(iStreamR); case 3: return new ZTBQueryNode_Difference(iStreamR); case 4: return new ZTBQueryNode_First(iStreamR); case 5: return new ZTBQueryNode_ID_Constant(iStreamR); case 6: return new ZTBQueryNode_ID_FromSource(iStreamR); case 7: return new ZTBQueryNode_Property(iStreamR); } throw runtime_error("ZTBQuery, sNodeFromStream, unknown node type"); }
static void sReadImageData(const ZStreamR& iStream, bool iInterlaced, const ZRect& iBounds, ZRef<ZDCPixmapRaster> ioRaster) { uint8 initialCodeSize = iStream.ReadUInt8(); StreamR_Chunk theSIC(iStream); ZStreamR_LZWDecode theSILZW(initialCodeSize, theSIC); ZDCPixmapNS::PixvalDesc sourcePixvalDesc(8, true); void* destBaseAddress = ioRaster->GetBaseAddress(); ZDCPixmapNS::RasterDesc destRasterDesc = ioRaster->GetRasterDesc(); vector<uint8> theRowBufferVector(iBounds.Width()); void* theRowBuffer = &theRowBufferVector[0]; if (iInterlaced) { for (int pass = 0; pass < 4; ++pass) { for (ZCoord currentY = iBounds.top + sInterlaceStart[pass]; currentY < iBounds.bottom; currentY += sInterlaceIncrement[pass]) { theSILZW.Read(theRowBuffer, iBounds.Width()); void* destRowAddress = destRasterDesc.CalcRowAddress(destBaseAddress, currentY); ZDCPixmapNS::sBlitRowPixvals(theRowBuffer, sourcePixvalDesc, 0, destRowAddress, destRasterDesc.fPixvalDesc, iBounds.left, iBounds.Width()); } } } else { for (ZCoord currentY = iBounds.top; currentY < iBounds.bottom; ++currentY) { theSILZW.Read(theRowBuffer, iBounds.Width()); void* destRowAddress = destRasterDesc.CalcRowAddress(destBaseAddress, currentY); ZDCPixmapNS::sBlitRowPixvals(theRowBuffer, sourcePixvalDesc, 0, destRowAddress, destRasterDesc.fPixvalDesc, iBounds.left, iBounds.Width()); } } }
static void sReadRLE4(const ZStreamR& iStream, ZCoord iWidth, ZCoord iHeight, size_t iRowBytes, bool iFlip, uint8* iBuffer) { ZCoord currentRow = 0; ZCoord currentCol = 0; bool done = false; while (!done) { uint8 count = iStream.ReadUInt8(); uint8 command = iStream.ReadUInt8(); if (count == 0) { switch (command) { case 0: // Move to start of next row { currentRow += 1; currentCol = 0; break; } case 1: // All done { done = true; break; } case 2: // Offset by some relative amount { currentCol += iStream.ReadUInt8(); currentRow += iStream.ReadUInt8(); break; } default: // Absolute data follows -- the length is the value of 'command' { uint8* rowStart = iBuffer + iRowBytes * (iFlip ? iHeight - currentRow - 1 : currentRow); uint8 hi, lo; for (int i = 0; i < command; ++i) { if ((i & 1) == 0) { uint8 data = iStream.ReadUInt8(); hi = data >> 4; lo = data & 0x0f; } if ((currentCol & 1) == 0) { if ((i & 1) == 0) rowStart[currentCol / 2] = hi << 4; else rowStart[currentCol / 2] = lo << 4; } else { if ((i & 1) == 0) rowStart[currentCol / 2] |= hi; else rowStart[currentCol / 2] |= lo; } ++currentCol; } switch (command & 0x03) { case 1: case 2: iStream.Skip(1); break; } break; } } } else {
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; } } }
ZTBQuery::SortSpec::SortSpec(const ZStreamR& iStreamR) : fPropName(iStreamR), fAscending(iStreamR.ReadBool()), fStrength(iStreamR.ReadUInt8()) {}
ZTBSpec::Comparator::Comparator(const ZStreamR& iStreamR) { fRel = (ERel)iStreamR.ReadUInt8(); fStrength = iStreamR.ReadUInt8(); }
static void sUnpackFromStream(const ZStreamR& inStream, ZCoord inSourceWidth, ZCoord inSourceHeight, unsigned short inSourceRowBytes, short inSourcePixelSize, const ZRGBColorPOD* inSourceColors, size_t inSourceColorTableSize, void* inDestBaseAddress, const ZDCPixmapNS::RasterDesc& inDestRasterDesc, const ZDCPixmapNS::PixelDesc& inDestPixelDesc) { // We're only supporting indexed pixels right now ZAssert(inSourcePixelSize == 1 || inSourcePixelSize == 2 || inSourcePixelSize == 4 || inSourcePixelSize == 8); ZDCPixmapNS::PixelDesc sourcePixelDesc(inSourceColors, inSourceColorTableSize); ZDCPixmapNS::PixvalDesc sourcePixvalDesc(inSourcePixelSize, true); if (inSourceRowBytes < 8) { // ah-ha! The bits aren't actually packed. This will be easy. uint8 lineBuffer[8]; for (ZCoord theScanLine = 0; theScanLine < inSourceHeight; ++theScanLine) { inStream.Read(lineBuffer, inSourceRowBytes); void* destRowAddress = inDestRasterDesc.CalcRowAddress(inDestBaseAddress, theScanLine); ZDCPixmapNS::sBlitRow(lineBuffer, sourcePixvalDesc, sourcePixelDesc, 0, destRowAddress, inDestRasterDesc.fPixvalDesc, inDestPixelDesc, 0, inSourceWidth); } } else { // Sometimes we get rows with length > rowBytes. Allocate some extra for slop. // Also note that the data is stored as multiples of rowBytes, which may represent more // pixels than inSourceWidth (if inSourceWidth % 4 != 0). So we have to check for // destinationH < inSourceWidth before we actually blit to the destination. vector<uint8> lineBufferVector(inSourceRowBytes + 80); uint8* lineBuffer = &lineBufferVector[0]; ZDCPixmapNS::PixvalAccessor destAccessor(inDestRasterDesc.fPixvalDesc); for (ZCoord theScanLine = 0; theScanLine < inSourceHeight; ++theScanLine) { void* destRowAddress = inDestRasterDesc.CalcRowAddress(inDestBaseAddress, theScanLine); size_t lineLen; if (inSourceRowBytes > 250 || inSourcePixelSize > 8) lineLen = inStream.ReadUInt16(); else lineLen = inStream.ReadUInt8(); if (lineLen > inSourceRowBytes + 80) ::sThrowBadFormat(); inStream.Read(lineBuffer, lineLen); ZCoord destinationH = 0; for (size_t j = 0; j < lineLen; /*no increment*/) { if (lineBuffer[j] & 0x80) { size_t repeatCount = (lineBuffer[j++] ^ 0xFF) + 2; ZRGBColorPOD theRGBColor; sourcePixelDesc.AsRGBColor(lineBuffer[j++], theRGBColor); uint32 destPixval = inDestPixelDesc.AsPixval(theRGBColor); for (size_t k = 0; k < repeatCount; ++k) { if (destinationH < inSourceWidth) destAccessor.SetPixval(destRowAddress, destinationH, destPixval); destinationH += 1; } } else { size_t realLength = lineBuffer[j] + 1; if (inSourceWidth > destinationH) { size_t countToCopy = min(realLength, size_t(inSourceWidth - destinationH)); ZDCPixmapNS::sBlitRow(lineBuffer, sourcePixvalDesc, sourcePixelDesc, j + 1, destRowAddress, inDestRasterDesc.fPixvalDesc, inDestPixelDesc, destinationH, countToCopy); destinationH += countToCopy; } j += realLength + 1; } } } } }
bool ZTSWatcherServerAsync::Read(const ZStreamR& iStreamR) { if (ZLOG(s, eDebug, "ZTSWatcherServerAsync")) s << "Read, start"; EReq theReq = (EReq)iStreamR.ReadUInt8(); switch (theReq) { case eReq_Close: { ZMutexLocker locker(fMutex); fSendClose = true; locker.Release(); ZStreamerWriter::Wake(); return false; } case eReq_IDs: { if (ZLOG(s, eDebug, "ZTSWatcherServerAsync")) s << "Read, eReq_IDs"; const size_t theIDsNeeded = iStreamR.ReadCount(); ZMutexLocker locker(fMutex); fIDsNeeded += theIDsNeeded; locker.Release(); ZStreamerWriter::Wake(); break; } case eReq_Sync: { if (ZLOG(s, eDebug, "ZTSWatcherServerAsync")) s << "Read, eReq_Sync"; vector<uint64> removedIDs; if (uint32 theCount = iStreamR.ReadCount()) { removedIDs.reserve(theCount); while (theCount--) removedIDs.push_back(iStreamR.ReadUInt64()); } vector<uint64> addedIDs; if (uint32 theCount = iStreamR.ReadCount()) { addedIDs.reserve(theCount); while (theCount--) addedIDs.push_back(iStreamR.ReadUInt64()); } vector<int64> removedQueries; if (uint32 theCount = iStreamR.ReadCount()) { removedQueries.reserve(theCount); while (theCount--) removedQueries.push_back(iStreamR.ReadInt64()); } vector<ZTSWatcher::AddedQueryCombo> addedQueries; if (uint32 theCount = iStreamR.ReadCount()) { addedQueries.reserve(theCount); while (theCount--) { const int64 theRefcon = iStreamR.ReadInt64(); const bool thePrefetch = iStreamR.ReadBool(); const size_t theSize = iStreamR.ReadCount(); ZTSWatcher::AddedQueryCombo theCombo(theSize); theCombo.fRefcon = theRefcon; theCombo.fPrefetch = thePrefetch; iStreamR.Read(theCombo.fMemoryBlock.GetPtrMutable(), theSize); addedQueries.push_back(theCombo); } } vector<uint64> writtenTupleIDs; vector<ZTuple> writtenTuples; bool writeNeededSort = false; if (uint32 theCount = iStreamR.ReadCount()) { writtenTupleIDs.reserve(theCount); writtenTuples.reserve(theCount); uint64 priorID = 0; while (theCount--) { const uint64 currentID = iStreamR.ReadUInt64(); if (priorID >= currentID) writeNeededSort = true; priorID = currentID; writtenTupleIDs.push_back(currentID); writtenTuples.push_back(ZTuple(iStreamR)); } if (writeNeededSort) spSort(writtenTupleIDs, writtenTuples); } ZMutexLocker locker(fMutex); ZAssert(fRemovedIDs.empty()); ZAssert(fAddedIDs.empty()); ZAssert(fRemovedQueries.empty()); ZAssert(fAddedQueries.empty()); ZAssert(fWrittenTupleIDs.empty()); ZAssert(fWrittenTuples.empty()); ZAssert(!fSyncNeeded); fRemovedIDs.swap(removedIDs); fAddedIDs.swap(addedIDs); fRemovedQueries.swap(removedQueries); fAddedQueries.swap(addedQueries); fWrittenTupleIDs.swap(writtenTupleIDs); fWrittenTuples.swap(writtenTuples); fSyncNeeded = true; locker.Release(); ZStreamerWriter::Wake(); break; } } return true; }