Пример #1
0
void PLSGIDecoder::Open (PLDataSource * pDataSrc)
{
  Trace (2, "Decoding SGI.\n");
  PLPixelFormat pf;
  readHeader (&m_Header, pDataSrc);

  bool bGreyscale = (m_Header.ZSize == 1 && static_cast<int>(m_Header.Colormap) == CMAP_NORMAL);

  switch (m_Header.ZSize)
  {
    case 1:
      if (bGreyscale) {
        pf = PLPixelFormat::L8;
      } else {
        pf = PLPixelFormat::I8;
      }
      break;
    case 2:
      throw PLTextException (PL_ERRFORMAT_NOT_SUPPORTED, "Two-channel SGI RGB files are not supported.");
      break;
    case 3:
      pf = PLPixelFormat::X8R8G8B8;
      break;
    case 4:
      // Image has alpha channel
      pf = PLPixelFormat::A8R8G8B8;      
  }
  if (m_Header.Dimension == 1)
  {
    throw PLTextException (PL_ERRFORMAT_NOT_SUPPORTED, "One-dimensional SGI RGB files are not supported.");
  }
  
  
  SetBmpInfo (PLPoint (m_Header.XSize, m_Header.YSize), PLPoint(0, 0), pf);
}
Пример #2
0
void PLDIBSection::internalCreate
    ( PLLONG Width,
      PLLONG Height,
      const PLPixelFormat& pf
    )
    // Create a new empty DIBSection.
    // Assumes that no memory is allocated before the call.
{
#ifdef MAX_BITMAP_SIZE
	if (GetMemNeeded (Width, Height, pf.GetBitsPerPixel())
      > MAX_BITMAP_SIZE)
	  throw PLTextException(PL_ERRDIB_TOO_LARGE, "Bitmap size too large.\n");
#endif

  int MemNeeded = sizeof (BITMAPINFOHEADER);
  if (pf.GetBitsPerPixel() <= 8)
  { // Color table exists
    MemNeeded += (1 << pf.GetBitsPerPixel())*sizeof (RGBQUAD);
  }

  m_pBMI = (BITMAPINFOHEADER*) malloc (MemNeeded);
  // out of memory?
  if (!m_pBMI)
    throw (PLTextException (PL_ERRNO_MEMORY, "Out of memory creating bitmap."));

  // Fill in the header info.
  m_pBMI->biSize = sizeof(BITMAPINFOHEADER);
  m_pBMI->biWidth = Width;
  m_pBMI->biHeight = Height;
  m_pBMI->biPlanes = 1;
  m_pBMI->biBitCount = pf.GetBitsPerPixel();
  m_pBMI->biCompression = BI_RGB;   // No compression
  m_pBMI->biSizeImage = 0;
  m_pBMI->biXPelsPerMeter = 0;
  m_pBMI->biYPelsPerMeter = 0;
  m_pBMI->biClrUsed = 0;           // Always use the whole palette.
  m_pBMI->biClrImportant = 0;

  // Create DIB section in shared memory
  m_hBitmap = CreateDIBSection (NULL, (BITMAPINFO *)m_pBMI,
                                DIB_RGB_COLORS, (void **)&m_pBits, 0, 0l);
  if (!m_hBitmap)
    throw (PLTextException (PL_ERRNO_MEMORY, "Out of memory creating bitmap."));

  // Set color table pointer & pointer to bits.
  initPointers ();

  initLocals (Width, Height, pf);

  PLASSERT_VALID (this);
}
Пример #3
0
HANDLE PLDIBSection::createCopyHandle
    ()
    // Creates a copy of the current bitmap in a global memory block
    // and returns a handle to this block.
{
  HANDLE  hCopy;

  int MemUsed = GetMemUsed();

  hCopy = (HANDLE) ::GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE,
                                  MemUsed);
  if (hCopy == NULL)
    throw (PLTextException (PL_ERRNO_MEMORY, "Out of memory creating bitmap."));

  long * lpCopy = (long *) ::GlobalLock((HGLOBAL) hCopy);

  int BPP = GetBitsPerPixel();
  int HeaderMem = sizeof (BITMAPINFOHEADER);
  if (BPP < 16)
  { // Color table exists
    HeaderMem += (1 << BPP)*sizeof (RGBQUAD);
  }
  memcpy (lpCopy, m_pBMI, HeaderMem);
  int BitsMem = GetBitsMemNeeded (GetWidth(), GetHeight(), BPP);
  memcpy (((PLBYTE *)lpCopy)+HeaderMem, m_pBits, BitsMem);

  ::GlobalUnlock((HGLOBAL) hCopy);

  return hCopy;
}
Пример #4
0
void PLFileSink::resizeMapping(size_t theNewSize) {
    if (m_pDataBuf) {
        if (munmap(m_pDataBuf, _myMappedSize) != 0) {
        }
        m_pDataBuf = 0;
        _myMappedSize = 0;
    }
    if (theNewSize > 0) {
        if (ftruncate(m_File, theNewSize) != 0) {
            throw PLTextException(PL_ERRINTERNAL, "error truncating to new size");
        }
        m_pDataBuf = (PLBYTE *) mmap(NULL, theNewSize, PROT_READ|PROT_WRITE,
                MAP_SHARED, m_File, 0);

        if (m_pDataBuf == MAP_FAILED) {
            std::cerr <<"mmap failed, got error "<< strerror(errno)<<std::endl;
            throw PLTextException(PL_ERRINTERNAL, "mmap failed");
        }
        _myMappedSize = theNewSize;
    }
}
Пример #5
0
size_t PLDataSink::WriteNBytes
    ( size_t   n,
    PLBYTE* pData
    )
{
  if (m_nCurPos+n > m_nMaxFileSize)
    throw PLTextException (PL_ERREND_OF_FILE,
          "Buffer overflow while encoding.\n");

  memcpy(m_pStartData + m_nCurPos, pData, n);
  m_nCurPos += n;
  return n;
}
Пример #6
0
void PLDIBSection::internalCreate
    ( BITMAPINFOHEADER* pBMI
    )
    // Creates a PLDIBSection from an existing bitmap pointer.
    // Assumes that no memory is allocated before the call.
{
#ifdef MAX_BITMAP_SIZE
	if (GetMemNeeded (pBMI->biWidth, pBMI->biHeight, pBMI->biBitCount)
      > MAX_BITMAP_SIZE)
	  throw PLTextException(PL_ERRDIB_TOO_LARGE, "Bitmap size too large.\n");
#endif

  int MemNeeded = sizeof (BITMAPINFOHEADER);
  if (pBMI->biBitCount < 16)
  { // Color table exists
    MemNeeded += (1 << pBMI->biBitCount)*sizeof (RGBQUAD);
  }

  m_pBMI = (BITMAPINFOHEADER *) malloc (MemNeeded);

  memcpy (m_pBMI, pBMI, MemNeeded);

  // Create DIB section in shared memory
  m_hBitmap = CreateDIBSection (NULL, (BITMAPINFO *)m_pBMI,
                                DIB_RGB_COLORS, (void **)&m_pBits, 0, 0l);
  if (!m_hBitmap)
    throw (PLTextException (PL_ERRNO_MEMORY, "Out of memory creating bitmap."));

  // Set color table pointer & pointer to bits.
  initPointers ();

  PLPixelFormat pf = pixelFormatFromBMI(m_pBMI);

  initLocals (m_pBMI->biWidth, m_pBMI->biHeight, pf);

  PLASSERT_VALID (this);
}
Пример #7
0
void PLSGIDecoder::GetImage (PLBmpBase & Bmp)
{
  switch (m_Header.Storage) 
  {
    case STORAGE_VERBATIM:
      readUncompressed(Bmp);
      break;
    case STORAGE_RLE:
      readRLE(Bmp);
      break;
    default:
      throw PLTextException (PL_ERRFORMAT_NOT_SUPPORTED, 
            "Unknown SGI RGB file compression format.");
  }
}
Пример #8
0
// now flush the data to disk
void PLFileSink::Close ()
{
#ifdef PL_FILE_MAPPING
#   ifdef _WIN32
  UnmapViewOfFile (m_pStartData);
  CloseHandle (m_hm);
  m_hm = NULL;
  ::SetFilePointer(m_hf,GetDataSize(),0,FILE_BEGIN);
  ::SetEndOfFile(m_hf); //Truncate the file to the right size
  CloseHandle (m_hf);
  m_hf = NULL;
#   else
  resizeMapping(GetDataSize());
  if (munmap(m_pDataBuf, GetDataSize()) != 0) {
    std::cerr <<"munmap failed, got error "<< strerror(errno)<<std::endl;
    throw PLTextException(PL_ERRINTERNAL, "munmap failed");
  }
  m_pDataBuf = NULL;
  close( m_File );
  m_File = 0;

#   endif
#else
  int towrite = GetDataSize();
  int written = fwrite( m_pStartData, 1, towrite, m_pFile );
#   ifndef _DEBUG
// avoid warnings
    (void)(towrite);
    (void)(written);
#   endif
  PLASSERT( written == towrite );
  fclose( m_pFile );
  m_pFile = 0;

  if (m_pDataBuf)
  {
    delete[] m_pDataBuf;
    m_pDataBuf = NULL;
  }
#endif

  PLDataSink::Close();
}
Пример #9
0
void PLSGIDecoder::readHeader
    ( SGIHeader * pHeader,
      PLDataSource * pDataSrc
    )
{
    pHeader->Magic     = ReadMWord (pDataSrc);
    pHeader->Storage   = ReadByte (pDataSrc);
    pHeader->bpc       = ReadByte (pDataSrc);
    pHeader->Dimension = ReadMWord (pDataSrc);
    pHeader->XSize     = ReadMWord (pDataSrc);
    pHeader->YSize     = ReadMWord (pDataSrc);
    pHeader->ZSize     = ReadMWord (pDataSrc);
    pHeader->PixMin    = ReadMLong (pDataSrc);
    pHeader->PixMax    = ReadMLong (pDataSrc);
    ReadMLong(pDataSrc);
    memcpy (pHeader->Name, (char *)pDataSrc->ReadNBytes(80), 80);
    pHeader->Colormap  = ReadMLong (pDataSrc);
    pDataSrc->Skip(404);

    if (pHeader->Magic != SGI_MAGIC)
    {
      throw PLTextException (PL_ERRWRONG_SIGNATURE, "SGI decoder invoked for non-SGI file.");
    }
}
Пример #10
0
void PLTIFFEncoder::DoTiffEncode (PLBmpBase* pBmp, TIFF* tif)
{
  uint32 l, c, image_length, image_width;
  // iterate over data
  PLBYTE **pla = pBmp->GetLineArray();
  PLASSERT( pla );

  image_length = (uint32) pBmp->GetHeight();
  image_width  = (uint32) pBmp->GetWidth();
  switch (pBmp->GetBitsPerPixel())
  {
    case 8:
      {
        // first, save the colormap
        uint16 red[256];
        uint16 green[256];
        uint16 blue[256];

        PLPixel32 * pPal = pBmp->GetPalette();
        PLASSERT( pPal );
        for (int i = 0; i < pBmp->GetNumColors(); i++, pPal++)
        {
          red[i]   = pPal->GetR ();
          green[i] = pPal->GetG ();
          blue[i]  = pPal->GetB ();
        }
        SetField( tif, TIFFTAG_COLORMAP, red, green, blue );
      }
      // fall-through

    case 1:  // TODO: a bit of error checking
      for (l = 0; l < image_length; l++)
        if(TIFFWriteScanline( tif, pla[l], l, 0 ) < 1) {
            throw PLTextException(PL_ERRINTERNAL, "TIFFWriteScanline failed");
        }
      break;

    case 24:
      {
        // TODO: check whether (r,g,b) components come in the correct order here...
        PLBYTE* pBuf = new PLBYTE[3*image_width];
        for (l = 0; l < image_length; l++)
        {
          for (c = 0; c < image_width; c++)
          {
            pBuf[c*3 + 0] = pla[l][c*sizeof(PLPixel24) + PL_RGBA_RED];
            pBuf[c*3 + 1] = pla[l][c*sizeof(PLPixel24) + PL_RGBA_GREEN];
            pBuf[c*3 + 2] = pla[l][c*sizeof(PLPixel24) + PL_RGBA_BLUE];
          }
          if(TIFFWriteScanline( tif, pBuf, l, 0 ) < 1) {
              throw PLTextException(PL_ERRINTERNAL, "TIFFWriteScanline failed");
          }
        }
        delete [] pBuf;
      }
      break;
    case 32:
      {
        // TODO: check whether (r,g,b) components come in the correct order here...
        if (pBmp->HasAlpha())
        {
          uint32 *plBuf = new uint32[image_width];
          for (l = 0; l < image_length; l++)
          {
            for (c = 0; c < image_width; c++)
            {
                // For 32 bit, TIFFLIB wants abgr long word packed...
                plBuf[c] = 
                    ((uint32)(pla[l][c*sizeof(PLPixel32) + PL_RGBA_ALPHA]) << 24) |
                    ((uint32)(pla[l][c*sizeof(PLPixel32) + PL_RGBA_BLUE])  << 16) |
                    ((uint32)(pla[l][c*sizeof(PLPixel32) + PL_RGBA_GREEN]) << 8 ) |
                    ((uint32)(pla[l][c*sizeof(PLPixel32) + PL_RGBA_RED]));
            }
            if(TIFFWriteScanline( tif, plBuf, l, 0 ) < 1) {
                throw PLTextException(PL_ERRINTERNAL, "TIFFWriteScanline failed");
            }
          }
          delete [] plBuf;
        }
        else
        {
          PLBYTE* pBuf = new PLBYTE[3*image_width];
          for (l = 0; l < image_length; l++)
          {
            for (c = 0; c < image_width; c++)
            {
              pBuf[c*3 + 0] = pla[l][c*sizeof(PLPixel32) + PL_RGBA_RED];
              pBuf[c*3 + 1] = pla[l][c*sizeof(PLPixel32) + PL_RGBA_GREEN];
              pBuf[c*3 + 2] = pla[l][c*sizeof(PLPixel32) + PL_RGBA_BLUE];
            }
            if(TIFFWriteScanline( tif, pBuf, l, 0 ) < 1) {
                throw PLTextException(PL_ERRINTERNAL, "TIFFWriteScanline failed");
            }
          }
          delete [] pBuf;
        }
      }
      break;

    default:
      PLASSERT(false);
      throw PLTextException(PL_ERRFORMAT_NOT_SUPPORTED, "unsupported bitsPerPixel");
  }
  // we could flush at this point, but TIFFClose will do it anyway
}
Пример #11
0
PLBYTE* PLMemSink::GetBytes() {
  if (m_pDataBuf)
    return m_pDataBuf;
  else
    throw PLTextException(PL_ERRINTERNAL, "Open was not called for CMemSink");
}