Esempio n. 1
0
//-----------------------------------------------------------------------------
CGContextRef CGBitmap::createCGContext ()
{
	CGContextRef context = 0;
	if (bits == 0)
	{
		allocBits ();
		if (imageSource)
			getCGImage ();
		if (image)
		{
			context = createCGContext ();
			if (context)
			{
				CGContextScaleCTM (context, 1, -1);
				CGContextDrawImage (context, CGRectMake (0, -size.y, size.x, size.y), image);
				CGContextScaleCTM (context, 1, -1);
				return context;
			}
		}
	}
	if (bits)
	{
		CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big;
		context = CGBitmapContextCreate (bits,
						size.x,
						size.y,
						8,
						getBytesPerRow (),
						GetCGColorSpace (),
						bitmapInfo);
		CGContextTranslateCTM (context, 0, (CGFloat)size.y);
		CGContextScaleCTM (context, 1, -1);
	}
	return context;
}
Esempio n. 2
0
//-----------------------------------------------------------------------------
CGImageRef CGBitmap::getCGImage ()
{
	if (image == 0 && imageSource)
	{
		const void* keys[] = {kCGImageSourceShouldCache, kCGImageSourceShouldPreferRGB32};
		const void* values[] = {kCFBooleanTrue, kCFBooleanTrue};
		CFDictionaryRef options = CFDictionaryCreate (NULL, keys, values, 2, NULL, NULL);
		image = CGImageSourceCreateImageAtIndex (imageSource, 0, options);
		CFRelease (imageSource);
		CFRelease (options);
		imageSource = 0;
	}
	if ((dirty || image == 0) && bits)
	{
		freeCGImage ();

		size_t rowBytes = getBytesPerRow ();
		size_t byteCount = rowBytes * size.y;
		size_t bitDepth = 32;

		CGDataProviderRef provider = CGDataProviderCreateWithData (NULL, bits, byteCount, NULL);
		CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big;
		image = CGImageCreate (size.x, size.y, 8, bitDepth, rowBytes, GetCGColorSpace (), bitmapInfo, provider, NULL, false, kCGRenderingIntentDefault);
		CGDataProviderRelease (provider);
		dirty = false;
	}
	return image;
}
Esempio n. 3
0
void PLIFF85Decoder::Open(PLDataSource * pDataSrc)
{

  // Check if the file is a valid IFF-85 file or not
  Trace(2, "Decoding IFF-85 header.\n");

  PLIFF85::Chunk chunk;

  if (PLIFF85::MakeID(reinterpret_cast<const char*> (pDataSrc->GetBufferPtr(sizeof chunk))) !=
        PLIFF85::ID_FORM)
  {
    raiseError(PL_ERRWRONG_SIGNATURE, "File is not a single-form IFF.");
  }

  readChunkHeader(chunk, pDataSrc);

  size_t totalSize = chunk.ckSize + sizeof chunk;
  size_t lumpIndex = sizeof chunk;

  // Now read the form type - we only know how to handle PBM and ILBM.
  chunk.ckID   = ReadMLong(pDataSrc);
  if (chunk.ckID == PLIFF85::ID_PBM)
  {
    Trace(2, "Form type: PBM\n");
  }
  else if (chunk.ckID == PLIFF85::ID_ILBM)
  {
    Trace(2, "Form type: ILBM\n");
  }
  else
  {
    raiseError(PL_ERRFORMAT_UNKNOWN, "Unknown form type.");
  }

  m_formType = chunk.ckID;
  lumpIndex += sizeof chunk.ckID;

  int numCMapElements = 0;

  m_viewMode = 0;

  // Now loop through the chunks, processing the header and cmap.
  // Stop when we find the body, so the data source is left in the correct
  // position to read it.
  bool  readBitmapHeader    = false;
  bool  readPalette         = false;
  bool  foundBody           = false;
  bool  done                = false;

  PLIFF85::LONG bodySize    = 0;

  while (!done)
  {
    readChunkHeader(chunk, pDataSrc);
    lumpIndex += sizeof chunk;

    if (chunk.ckID == PLIFF85::ID_BMHD)
    {
      if (size_t(chunk.ckSize) != sizeof m_bitmapHeader)
      {
        raiseError(PL_ERRFORMAT_UNKNOWN, "Unexpected header size.");
      }

      m_bitmapHeader.w                  = ReadMWord(pDataSrc);
      m_bitmapHeader.h                  = ReadMWord(pDataSrc);
      m_bitmapHeader.x                  = ReadMWord(pDataSrc);
      m_bitmapHeader.y                  = ReadMWord(pDataSrc);
      m_bitmapHeader.nPlanes            = ReadByte(pDataSrc);
      m_bitmapHeader.masking            = ReadByte(pDataSrc);
      m_bitmapHeader.compression        = ReadByte(pDataSrc);
      m_bitmapHeader.pad1               = ReadByte(pDataSrc);
      m_bitmapHeader.transparentColor   = ReadMWord(pDataSrc);
      m_bitmapHeader.xAspect            = ReadByte(pDataSrc);
      m_bitmapHeader.yAspect            = ReadByte(pDataSrc);
      m_bitmapHeader.pageWidth          = ReadMWord(pDataSrc);
      m_bitmapHeader.pageHeight         = ReadMWord(pDataSrc);

      switch (m_bitmapHeader.masking)
      {
        case PLIFF85::mskNone:
          Trace(2, "No masking.\n");
          break;
        case PLIFF85::mskHasMask:
          Trace(2, "Has mask plane.\n");
          break;
        case PLIFF85::mskHasTransparentColor:
          Trace(2, "Has transparent colour.\n");
          break;
        case PLIFF85::mskLasso:
          Trace(2, "Lasso");
          break;
        default:
          raiseError(PL_ERRFORMAT_UNKNOWN, "Unknown masking technique.");
          break;
      }

      switch (m_bitmapHeader.compression)
      {
        case PLIFF85::cmpNone:
          Trace(2, "No compression.\n");
          break;
        case PLIFF85::cmpByteRun1:
          Trace(2, "Byte run encoding.\n");
          break;
        default:
          raiseError(PL_ERRFORMAT_UNKNOWN, "Unknown compression method.");
          break;
      }
      readBitmapHeader = true;
    }
    else if (chunk.ckID == PLIFF85::ID_CMAP)
    {
      // The palette.
      PLCOMPILER_ASSERT(sizeof(PLIFF85::ColorRegister) == 3);

      numCMapElements = chunk.ckSize / 3;

      for (int i = 0; i < numCMapElements; ++i)
      {
        const PLIFF85::ColorRegister * pElement =
          reinterpret_cast<const PLIFF85::ColorRegister *> (pDataSrc->ReadNBytes(3));
        m_pal[i].Set(pElement->red, pElement->green, pElement->blue, 0xFF);
      }
      readPalette = true;
    }
    else if (chunk.ckID == PLIFF85::ID_CAMG)
    {
      // The viewport mode.
      if (size_t(chunk.ckSize) != sizeof m_viewMode)
      {
        raiseError(PL_ERRFORMAT_UNKNOWN, "Unexpected CAMG size.");
      }
      m_viewMode = ReadMLong(pDataSrc);
      #if DETAILED_TRACE
        std::ostringstream strTrace;
        strTrace << "View mode " << std::hex << std::showbase << m_viewMode << ".\n";
        Trace(2, strTrace.str().c_str());
      #endif
    }
    else if (chunk.ckID == PLIFF85::ID_BODY)
    {
      bodySize      = chunk.ckSize;
      foundBody     = true;
      done          = true;
    }
    else
    {
      // Some other chunk type - ignore it.
      pDataSrc->Skip(chunk.ckSize);
    }

    if (!done)
    {
      lumpIndex += chunk.ckSize;
    }

    if (lumpIndex >= totalSize - 1)
    {
      done = true;
    }
  }

  // We must have seen a header, cmap and body at this point.
  if (!readBitmapHeader)
  {
    raiseError(PL_ERRFORMAT_UNKNOWN, "Header not found.");
  }

  if ((!readPalette) && (m_bitmapHeader.nPlanes <= 8))
  {
    raiseError(PL_ERRFORMAT_UNKNOWN, "Palette not found.");
  }

  if (!foundBody)
  {
    raiseError(PL_ERRFORMAT_UNKNOWN, "Body not found.");
  }

  // Check the body is the expected size ...
  if (m_bitmapHeader.compression == PLIFF85::cmpNone)
  {
    if (bodySize != getBytesPerRow() * m_bitmapHeader.h)
    {
      raiseError(PL_ERRFORMAT_UNKNOWN, "Unexpected body size.");
    }
  }

  // ... and that it does not extend beyond the end of the form.
  if (lumpIndex + bodySize > totalSize)
  {
    raiseError(PL_ERRFORMAT_UNKNOWN, "Body extends beyond form.");
  }

  // Too many CMAP entries probably indicates an error.
  const int maxExpectedCMapElements = int(((m_viewMode & PLIFF85::viewHAM) != 0) ?
    pow(2.0, m_bitmapHeader.nPlanes - 2) :
    pow(2.0, m_bitmapHeader.nPlanes));

  if (numCMapElements > maxExpectedCMapElements)
  {
    raiseError(PL_ERRFORMAT_UNKNOWN, "Too many CMAP entries.");
  }

  PLPixelFormat pf;
  int DestBPP = m_bitmapHeader.nPlanes;
  bool bAlpha = (m_bitmapHeader.masking == PLIFF85::mskHasTransparentColor);

  if ((DestBPP > 8)
  ||  ((m_viewMode & PLIFF85::viewHAM) != 0)
  ||  (m_bitmapHeader.masking == PLIFF85::mskHasTransparentColor))
  {
    if (bAlpha) {
      pf = PLPixelFormat::A8R8G8B8;
    } else {
      pf = PLPixelFormat::X8R8G8B8;
    }
  }
  else 
  {
    pf = PLPixelFormat::I8;
  }

  SetBmpInfo(PLPoint(m_bitmapHeader.w, m_bitmapHeader.h), PLPoint(0, 0), pf);
} // Open
Esempio n. 4
0
void PLIFF85Decoder::GetImage(PLBmpBase & Bmp)
{
  Trace(2, "Decoding IFF-85 body.\n");

  if (GetBitsPerPixel() == 8)
  {
    Bmp.SetPalette(&m_pal[0]);
  }

  // Decode each row into local storage, further processing depends on
  // form type.
  const int bytes_per_row = getBytesPerRow();

  std::vector<PLBYTE> buf(bytes_per_row);

  for (int row = 0; row < m_bitmapHeader.h; ++row)
  {
    #if DETAILED_TRACE
      std::ostringstream strTrace;
      strTrace << "#Row " << row << ".\n";
      Trace(3, strTrace.str().c_str());
    #endif

    if (m_bitmapHeader.compression == PLIFF85::cmpByteRun1)
    {
      readCompressedRow(&buf[0], m_pDataSrc, bytes_per_row);
    }
    else
    {
      PLASSERT(m_bitmapHeader.compression == PLIFF85::cmpNone);
      readUncompressedRow(&buf[0], m_pDataSrc, bytes_per_row);
    }

    std::vector<PLBYTE> decodedBuf(m_bitmapHeader.w * GetBitsPerPixel() / 8);

    if (m_formType == PLIFF85::ID_PBM)
    {
      // The number of bytes we want to output may be less than the number
      // we have read in, as the input must have an even number of bytes per
      // plane (which can produce a lot of unnecessary padding for a PBM).
      const int bytes_per_row = m_bitmapHeader.w * GetBitsPerPixel() / 8;
      decodedBuf.assign(buf.begin(), buf.begin() + bytes_per_row);
    }
    else
    {
      PLASSERT(m_formType == PLIFF85::ID_ILBM);

      for (int bp = 0; bp < m_bitmapHeader.nPlanes; ++bp)
      {
        const int start_index = bp * bytes_per_row / m_bitmapHeader.nPlanes;
        for (int i = 0; i < m_bitmapHeader.w; ++i)
        {
          // Get the byte we're interested in.
          PLBYTE the_byte = buf[start_index + i / 8];
          // Isolate the bit we're interested in.
          the_byte &= static_cast<PLBYTE> (1 << (7 - (i % 8)));
          // Now shift the bit to the correct position for this plane.
          if ((7 - (i % 8)) > bp)
          {
            the_byte >>= 7 - (i % 8) - bp;
          }
          else
          {
            the_byte <<= bp - (7 - (i % 8));
          }
          decodedBuf[i] |= the_byte;
        }
      }
    }