예제 #1
0
/*******************************************************************************
 * 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;
}
예제 #2
0
void SkGlyphCache::validate() const {
#ifdef SK_DEBUG_GLYPH_CACHE
    forceValidate();
#endif
}