/******************************************************************************* * Parser Definitions ******************************************************************************/ bool KAbstractHdrParserPrivate::parse() { // Initialize lexer nextChar(); if(!readExpect("#?RADIANCE\n")) { qFatal("No #?RADIANCE header, the file may be corrupt or invalid."); return false; } forceValidate(); nextToken(); // Read the Key/Value pairs for (;;) { if (peekToken() == PT_ENDOFHEADER) break; switch (nextToken()) { case PT_ERROR: qFatal("Encountered an error! Aborting"); return false; case PT_EOF: return true; case PT_KEYVALUE: m_parser->onKeyValue(m_key.c_str(), m_value.c_str()); case PT_ENDOFHEADER: break; } } // Read the data parseDimension(); parseDimension(); m_parser->onResolution(m_xOrder, m_yOrder, m_xSize, m_ySize); // Start parsing the data Rgbe color; RleCode rle; float *dest = m_parser->beginData(); int count; size_t repeat = 0; unsigned invalidCount = 0; unsigned char *scanline = new unsigned char[4 * m_xSize]; unsigned char *ptr, *end; int scanlines = 0; color = nextColor(); while (scanlines != m_ySize) { // Check for invalid color which marks RLE pixel repeat // Consecutive repeat invalid pixels increments repeat count. if (color.r == 1 && color.g == 1 && color.b == 1) { qFatal("Untested! Possibly incorrect!"); while (color.r == 1 && color.g == 1 && color.b == 1) { repeat += (color.e << (invalidCount * 8)); color = nextColor(); ++invalidCount; } while (repeat) { writeColor(dest, color); --repeat; } } // Check for invalid color which marks per-element RLE if (color.r == 2 && color.g == 2) { // Check scanline width if (((color.b << 8) | color.e) != m_xSize) { qFatal("Incorrect encoded scanline width! Expected `%d`, got `%d`", m_xSize, int((color.r << 8) | color.e)); } // Read all channels ptr = &scanline[0]; int written = 0; for (int channel = 0; channel < 4; ++channel) { end = &scanline[(channel+1)*m_xSize]; while (ptr < end) { rle = nextRle(); if (rle.run > 128) { count = int(rle.run) - 128; Q_ASSERT(count != 0); Q_ASSERT(count <= end - ptr); while (count > 0) { ++written; *ptr++ = rle.color; --count; } } else { count = int(rle.run) - 1; Q_ASSERT(count != -1); Q_ASSERT(count <= end - ptr); *ptr++ = rle.color; ++written; while (count > 0) { ++written; *ptr++ = nextChar(); --count; } } } } // Output the scanline data writeScanline(dest, scanline, scanlines); ++scanlines; } color = nextColor(); } m_parser->endData(); delete [] scanline; return false; }
void SkGlyphCache::validate() const { #ifdef SK_DEBUG_GLYPH_CACHE forceValidate(); #endif }