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 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; }
void ZStreamW_Null::Internal_CopyFrom(const ZStreamR& iStreamR, uint64 iCount, uint64* oCountRead, uint64* oCountWritten) { uint64 countSkipped; iStreamR.Skip(iCount, &countSkipped); if (oCountRead) *oCountRead = countSkipped; if (oCountWritten) *oCountWritten = countSkipped; }
void ZStreamWPos_Null::Internal_CopyFrom(const ZStreamR& iStreamR, uint64 iCount, uint64* oCountRead, uint64* oCountWritten) { uint64 countSkipped; iStreamR.Skip(iCount, &countSkipped); if (oCountRead) *oCountRead = countSkipped; if (oCountWritten) *oCountWritten = countSkipped; fPosition += countSkipped; fSize = max(fSize, fPosition); }
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 {
static void sReadPixmap(const ZStreamR& inStream, ZDCPixmap& outPixmap) { uint16 rowBytes = inStream.ReadUInt16(); if (!(rowBytes & 0x8000)) ::sThrowBadFormat(); rowBytes &= 0x7FFF; ZRect bounds; bounds.top = inStream.ReadInt16(); bounds.left = inStream.ReadInt16(); bounds.bottom = inStream.ReadInt16(); bounds.right = inStream.ReadInt16(); inStream.ReadInt16(); // version inStream.ReadInt16(); // packType inStream.ReadInt32(); // packSize inStream.ReadInt32(); // hRes inStream.ReadInt32(); //vRes short pixelType = inStream.ReadInt16(); // pixelType short pixelSize = inStream.ReadInt16(); // pixelSize short cmpCount = inStream.ReadInt16(); // cmpCount short cmpSize = inStream.ReadInt16(); // cmpSize inStream.ReadInt32(); // planeBytes inStream.ReadInt32(); // pmTable inStream.ReadInt32(); // pmReserved // We only deal with pixel type of 0 (indexed pixels) if (pixelType != 0) ::sThrowUnsupportedFormat(); // indexed pixels have a cmpCount of 1 if (cmpCount != 1) ::sThrowBadFormat(); // pixelSize and cmpSize should be equal for indexed pixels if (pixelSize != cmpSize) ::sThrowBadFormat(); // Next on the stream is the color table vector<ZRGBColor> theColorTable; inStream.ReadInt32(); // ctSeed inStream.ReadInt16(); // ctFlags short ctSize = inStream.ReadInt16(); for (int i = 0; i <= ctSize; ++i) { inStream.ReadInt16(); // colorSpecIndex ZRGBColor theColor; theColor.red = inStream.ReadUInt16(); theColor.green = inStream.ReadUInt16(); theColor.blue = inStream.ReadUInt16(); theColorTable.push_back(theColor); } // Now we have the source rect inStream.Skip(8); // and the destination rect inStream.Skip(8); // Penultimately we have the mode inStream.ReadUInt16(); // The remaining data is the packed pixels. Allocate our ZDCPixmap // using the size we read in, but with no initialized data. ZDCPixmap thePixmap(bounds.Size(), ZDCPixmapNS::eFormatEfficient_Color_32); void* baseAddress = thePixmap.GetBaseAddress(); ZDCPixmapNS::RasterDesc theRasterDesc = thePixmap.GetRasterDesc(); ZDCPixmapNS::PixelDesc thePixelDesc = thePixmap.GetPixelDesc(); ::sUnpackFromStream(inStream, bounds.Width(), bounds.Height(), rowBytes, pixelSize, &theColorTable[0], theColorTable.size(), baseAddress, theRasterDesc, thePixelDesc); outPixmap = thePixmap; }