// part of this being separated allows for us to play nicely with the setjmp of libpng bool ImageSourcePng::loadHeader() { bool success = true; if( setjmp( png_jmpbuf(mPngPtr) ) ) { success = false; } else { png_read_info( mPngPtr, mInfoPtr ); png_uint_32 width, height; int bitDepth, colorType, interlaceType, compressionType, filterMethod; if( ! png_get_IHDR( mPngPtr, mInfoPtr, &width, &height, &bitDepth, &colorType, &interlaceType, &compressionType, &filterMethod ) ) { png_destroy_read_struct( &mPngPtr, &mInfoPtr, (png_infopp)NULL ); mPngPtr = 0; return false; } setSize( width, height ); setDataType( ( bitDepth == 16 ) ? ImageIo::UINT16 : ImageIo::UINT8 ); #ifdef CINDER_LITTLE_ENDIAN png_set_swap( mPngPtr ); #endif switch( colorType ) { case PNG_COLOR_TYPE_GRAY: setColorModel( ImageIo::CM_GRAY ); setChannelOrder( ImageIo::Y ); break; case PNG_COLOR_TYPE_GRAY_ALPHA: setColorModel( ImageIo::CM_GRAY ); setChannelOrder( ImageIo::YA ); break; case PNG_COLOR_TYPE_RGB: case PNG_COLOR_TYPE_PALETTE: setColorModel( ImageIo::CM_RGB ); setChannelOrder( ImageIo::RGB ); break; case PNG_COLOR_TYPE_RGB_ALPHA: setColorModel( ImageIo::CM_RGB ); setChannelOrder( ImageIo::RGBA ); break; default: throw ImageSourcePngException( "Unexpected png color type." ); } png_set_expand_gray_1_2_4_to_8( mPngPtr ); png_set_palette_to_rgb( mPngPtr ); png_set_tRNS_to_alpha( mPngPtr ); png_read_update_info( mPngPtr, mInfoPtr ); } return success; }
ImageTargetGWorld::ImageTargetGWorld( ImageSourceRef imageSource ) : ImageTarget(), mGWorld( 0 ), mPixMap( 0 ) { setSize( (size_t)imageSource->getWidth(), (size_t)imageSource->getHeight() ); OSType formatType; // for now all we support is 8 bit RGBA setDataType( ImageIo::UINT8 ); formatType = k32ARGBPixelFormat; setChannelOrder( ImageIo::ARGB ); setColorModel( ImageIo::CM_RGB ); ::Rect boundsRect; boundsRect.left = boundsRect.top = 0; boundsRect.right = (short)imageSource->getWidth(); boundsRect.bottom = (short)imageSource->getHeight(); if( ::QTNewGWorld( &mGWorld, formatType, &boundsRect, NULL, NULL, 0 ) != noErr ) throw ImageIoException(); mPixMap = ::GetGWorldPixMap( mGWorld ); if( ! ::LockPixels( mPixMap ) ) { ::DisposeGWorld( mGWorld ); throw ImageIoException(); } #if defined( CINDER_MSW ) mData = reinterpret_cast<uint8_t*>( (**mPixMap).baseAddr ); mRowBytes = ( (**mPixMap).rowBytes ) & 0x3FFF; #else mData = reinterpret_cast<uint8_t*>( ::GetPixBaseAddr( mPixMap ) ); mRowBytes = ::GetPixRowBytes( mPixMap ); #endif }
ImageSourceChannel( const ChannelT<T> &channel ) : ImageSource() { mWidth = channel.getWidth(); mHeight = channel.getHeight(); setColorModel( ImageIo::CM_GRAY ); setChannelOrder( ImageIo::Y ); if( channel.getIncrement() != 1 ) setCustomPixelInc( channel.getIncrement() ); if( boost::is_same<T,uint8_t>::value ) { setDataType( ImageIo::UINT8 ); mChannel8u = *reinterpret_cast<const Channel8u*>( &channel ); // register reference to 'channel' } else if( boost::is_same<T,uint16_t>::value ) { setDataType( ImageIo::UINT16 ); mChannel16u = *reinterpret_cast<const Channel16u*>( &channel ); // register reference to 'channel' } else if( boost::is_same<T,float>::value ) { setDataType( ImageIo::FLOAT32 ); mChannel32f = *reinterpret_cast<const Channel32f*>( &channel ); // register reference to 'channel' } else throw; // this channel seems to be a type we've never met mRowBytes = channel.getRowBytes(); mData = reinterpret_cast<const uint8_t*>( channel.getData() ); }
ImageTargetCvPixelBuffer::ImageTargetCvPixelBuffer( ImageSourceRef imageSource, bool convertToYpCbCr ) : ImageTarget(), mPixelBufferRef( 0 ), mConvertToYpCbCr( convertToYpCbCr ) { setSize( (size_t)imageSource->getWidth(), (size_t)imageSource->getHeight() ); //http://developer.apple.com/mac/library/qa/qa2006/qa1501.html // if we're converting to YCbCr, we'll load all of the data as RGB in terms of ci::ImageIo // but we run color space conversion over it later in the finalize method OSType formatType; if( ! mConvertToYpCbCr ) { switch( imageSource->getDataType() ) { // for now all we support is 8 bit RGB(A) case ImageIo::UINT16: case ImageIo::FLOAT32: case ImageIo::UINT8: setDataType( ImageIo::UINT8 ); if( imageSource->hasAlpha () ) { formatType = k32ARGBPixelFormat; setChannelOrder( ImageIo::ARGB ); } else { formatType = k24RGBPixelFormat; setChannelOrder( ImageIo::RGB ); } setColorModel( ImageIo::CM_RGB ); break; default: throw ImageIoException(); } } else { formatType = 'v408';/*k4444YpCbCrA8PixelFormat;*/ setDataType( ImageIo::UINT8 ); setChannelOrder( ImageIo::RGBA ); setColorModel( ImageIo::CM_RGB ); } if( ::CVPixelBufferCreate( kCFAllocatorDefault, imageSource->getWidth(), imageSource->getHeight(), formatType, NULL, &mPixelBufferRef ) != kCVReturnSuccess ) throw ImageIoException(); if( ::CVPixelBufferLockBaseAddress( mPixelBufferRef, 0 ) != kCVReturnSuccess ) throw ImageIoException(); mData = reinterpret_cast<uint8_t*>( ::CVPixelBufferGetBaseAddress( mPixelBufferRef ) ); mRowBytes = ::CVPixelBufferGetBytesPerRow( mPixelBufferRef ); }
ImageSourceOpenNIUserMask( uint8_t *buffer, int w, int h, shared_ptr<UserTracker::Obj> ownerObj ) : ImageSource(), mData( buffer ), mOwnerObj( ownerObj ) { setSize( w, h ); setColorModel( ImageIo::CM_GRAY ); setChannelOrder( ImageIo::Y ); setDataType( ImageIo::UINT8 ); }
void ImageSourceFileRadiance::loadStream( IStreamRef stream ) { setDataType( ImageIo::FLOAT32 ); setColorModel( ImageIo::CM_RGB ); setChannelOrder( ImageIo::RGB ); char str[200]; stream->readData( str, 10 ); if( memcmp( str, "#?RADIANCE", 10 ) ) throw ImageSourceFileRadianceException( "Invalid header" ); stream->seekRelative( 1 ); char cmd[200]; int i = 0; char c = 0, oldc; while( true ) { oldc = c; stream->read( &c ); if( c == 0xa && oldc == 0xa ) break; cmd[i++] = c; } char resolution[200]; i = 0; while( true ) { stream->read( &c ); resolution[i++] = c; if( c == 0xa ) break; } int width, height; #if defined( CINDER_WINRT ) if( ! sscanf_s( resolution, "-Y %d +X %d", &height, &width ) ) #else if( ! sscanf( resolution, "-Y %d +X %d", &height, &width ) ) #endif throw ImageSourceFileRadianceException( "Unable to parse size" ); setSize( width, height ); mRgbData = std::unique_ptr<float[]>( new float[width * height * 3] ); std::unique_ptr<RgbePixel[]> scanline( new RgbePixel[width] ); // convert image float *cols = mRgbData.get(); for( int y = height - 1; y >= 0; y-- ) { if( ! decrunchScanline( scanline.get(), width, stream.get() ) ) break; workOnRgbeScanline( scanline.get(), width, cols ); cols += width * 3; } }
ImageTargetFileTinyExr::ImageTargetFileTinyExr( DataTargetRef dataTarget, ImageSourceRef imageSource, ImageTarget::Options options, const std::string & /*extensionData*/ ) { if( ! dataTarget->providesFilePath() ) { throw ImageIoExceptionFailedWrite( "ImageTargetFileTinyExr only supports writing to files." ); } mFilePath = dataTarget->getFilePath(); setSize( imageSource->getWidth(), imageSource->getHeight() ); ImageIo::ColorModel cm = options.isColorModelDefault() ? imageSource->getColorModel() : options.getColorModel(); switch( cm ) { case ImageIo::ColorModel::CM_RGB: mNumComponents = ( imageSource->hasAlpha() ) ? 4 : 3; setColorModel( ImageIo::ColorModel::CM_RGB ); setChannelOrder( ( mNumComponents == 3 ) ? ImageIo::ChannelOrder::BGR : ImageIo::ChannelOrder::ABGR ); if( mNumComponents == 3 ) mChannelNames = { "G", "B", "R" }; else mChannelNames = { "A", "G", "B", "R" }; break; case ImageIo::ColorModel::CM_GRAY: mNumComponents = ( imageSource->hasAlpha() ) ? 2 : 1; setColorModel( ImageIo::ColorModel::CM_GRAY ); setChannelOrder( ( mNumComponents == 2 ) ? ImageIo::ChannelOrder::YA : ImageIo::ChannelOrder::Y ); if( mNumComponents == 2 ) mChannelNames = { "Y", "A" }; else mChannelNames = { "Y" }; break; default: throw ImageIoExceptionIllegalColorModel(); } // TODO: consider supporting half float and uint types as well setDataType( ImageIo::DataType::FLOAT32 ); mData.resize( mHeight * imageSource->getWidth() * mNumComponents ); }
ImageTargetFileStbImage::ImageTargetFileStbImage( DataTargetRef dataTarget, ImageSourceRef imageSource, ImageTarget::Options options, const std::string &extensionData ) { if( ! dataTarget->providesFilePath() ) { throw ImageIoExceptionFailedWrite( "ImageTargetFileStbImage only supports writing to files." ); } mFilePath = dataTarget->getFilePath(); setSize( imageSource->getWidth(), imageSource->getHeight() ); ImageIo::ColorModel cm = options.isColorModelDefault() ? imageSource->getColorModel() : options.getColorModel(); switch( cm ) { case ImageIo::ColorModel::CM_RGB: mNumComponents = ( imageSource->hasAlpha() ) ? 4 : 3; setColorModel( ImageIo::ColorModel::CM_RGB ); setChannelOrder( ( mNumComponents == 4 ) ? ImageIo::ChannelOrder::RGBA : ImageIo::ChannelOrder::RGB ); break; case ImageIo::ColorModel::CM_GRAY: mNumComponents = ( imageSource->hasAlpha() ) ? 2 : 1; setColorModel( ImageIo::ColorModel::CM_GRAY ); setChannelOrder( ( mNumComponents == 2 ) ? ImageIo::ChannelOrder::YA : ImageIo::ChannelOrder::Y ); break; default: throw ImageIoExceptionIllegalColorModel(); } mExtension = extensionData; if( mExtension == "hdr" ) { // Radiance files are always float* setDataType( ImageIo::DataType::FLOAT32 ); mRowBytes = mNumComponents * imageSource->getWidth() * sizeof(float); } else { setDataType( ImageIo::DataType::UINT8 ); mRowBytes = mNumComponents * imageSource->getWidth() * sizeof(float); } mData = std::unique_ptr<uint8_t[]>( new uint8_t[mWidth * mRowBytes] ); }
ImageTargetChannel( ChannelT<T> *channel ) : mChannel( channel ) { if( boost::is_same<T,float>::value ) setDataType( ImageIo::FLOAT32 ); else if( boost::is_same<T,uint16_t>::value ) setDataType( ImageIo::UINT16 ); else if( boost::is_same<T,uint8_t>::value ) setDataType( ImageIo::UINT8 ); else throw; // what is this? setColorModel( ImageIo::CM_GRAY ); setChannelOrder( ImageIo::Y ); }
ImageSourceSurface( const SurfaceT<T> &surface ) : ImageSource() { mWidth = surface.getWidth(); mHeight = surface.getHeight(); setColorModel( ImageIo::CM_RGB ); setChannelOrder( ImageIo::ChannelOrder( surface.getChannelOrder().getImageIoChannelOrder() ) ); if( boost::is_same<T,uint8_t>::value ) { setDataType( ImageIo::UINT8 ); mSurface8u = *reinterpret_cast<const Surface8u*>( &surface ); // register reference to 'surface' } else if( boost::is_same<T,uint16_t>::value ) { setDataType( ImageIo::UINT16 ); mSurface16u = *reinterpret_cast<const Surface16u*>( &surface ); // register reference to 'surface' } else if( boost::is_same<T,float>::value ) { setDataType( ImageIo::FLOAT32 ); mSurface32f = *reinterpret_cast<const Surface32f*>( &surface ); // register reference to 'surface' } else throw; // this surface seems to be a type we've never met mRowBytes = surface.getRowBytes(); mData = reinterpret_cast<const uint8_t*>( surface.getData() ); }
ImageSourceFileTinyExr::ImageSourceFileTinyExr( DataSourceRef dataSource, ImageSource::Options /*options*/ ) { mExrImage.reset( new EXRImage ); const char *error; InitEXRImage( mExrImage.get() ); int status = 0; if( dataSource->isFilePath() ) { status = ParseMultiChannelEXRHeaderFromFile( mExrImage.get(), dataSource->getFilePath().string().c_str(), &error ); if( status != 0 ) throw ImageIoExceptionFailedLoadTinyExr( string( "Failed to parse OpenEXR header; Error message: " ) + error ); status = LoadMultiChannelEXRFromFile( mExrImage.get(), dataSource->getFilePath().string().c_str(), &error ); if( status != 0 ) throw ImageIoExceptionFailedLoadTinyExr( string( "Failed to parse OpenEXR file; Error message: " ) + error ); } else { BufferRef buffer = dataSource->getBuffer(); status = ParseMultiChannelEXRHeaderFromMemory( mExrImage.get(), (const unsigned char*)buffer->getData(), &error ); if( status != 0 ) throw ImageIoExceptionFailedLoadTinyExr( string( "Failed to parse OpenEXR header; Error message: " ) + error ); status = LoadMultiChannelEXRFromMemory( mExrImage.get(), (const unsigned char*)buffer->getData(), &error ); if( status != 0 ) throw ImageIoExceptionFailedLoadTinyExr( string( "Failed to parse OpenEXR file; Error message: " ) + error ); } // verify that the channels are all the same size; currently we don't support variably sized channels int pixelType = mExrImage->pixel_types[0]; for( int c = 1; c < mExrImage->num_channels; ++c ) { if( pixelType != mExrImage->pixel_types[c] ) throw ImageIoExceptionFailedLoadTinyExr( "TinyExr: heterogneous channel data types not supported" ); } switch( pixelType ) { case TINYEXR_PIXELTYPE_HALF: setDataType( ImageIo::FLOAT16 ); break; case TINYEXR_PIXELTYPE_FLOAT: setDataType( ImageIo::FLOAT32 ); break; default: throw ImageIoExceptionFailedLoadTinyExr( "TinyExr: Unknown data type" ); break; } setSize( mExrImage->width, mExrImage->height ); switch( mExrImage->num_channels ) { case 3: setColorModel( ImageIo::CM_RGB ); setChannelOrder( ImageIo::ChannelOrder::RGB ); break; case 4: setColorModel( ImageIo::CM_RGB ); setChannelOrder( ImageIo::ChannelOrder::RGBA ); break; default: throw ImageIoExceptionFailedLoadTinyExr( "TinyExr: Unsupported number of channels (" + to_string( mExrImage->num_channels ) + ")" ); } }
ImageTargetSurface<T>::ImageTargetSurface( SurfaceT<T> *aSurface ) : ImageTarget(), mSurface( aSurface ) { if( boost::is_same<T,float>::value ) setDataType( ImageIo::FLOAT32 ); else if( boost::is_same<T,uint16_t>::value ) setDataType( ImageIo::UINT16 ); else if( boost::is_same<T,uint8_t>::value ) setDataType( ImageIo::UINT8 ); else throw; // what is this? setColorModel( ImageIo::CM_RGB ); // set the target's ChannelT order based on the SurfaceT's switch ( mSurface->getChannelOrder().getCode() ) { case SurfaceChannelOrder::RGBA: setChannelOrder( ImageIo::RGBA ); break; case SurfaceChannelOrder::BGRA: setChannelOrder( ImageIo::BGRA ); break; case SurfaceChannelOrder::ARGB: setChannelOrder( ImageIo::ARGB ); break; case SurfaceChannelOrder::ABGR: setChannelOrder( ImageIo::ABGR ); break; case SurfaceChannelOrder::RGBX: setChannelOrder( ImageIo::RGBX ); break; case SurfaceChannelOrder::BGRX: setChannelOrder( ImageIo::BGRX ); break; case SurfaceChannelOrder::XRGB: setChannelOrder( ImageIo::XRGB ); break; case SurfaceChannelOrder::XBGR: setChannelOrder( ImageIo::XBGR ); break; case SurfaceChannelOrder::RGB: setChannelOrder( ImageIo::RGB ); break; case SurfaceChannelOrder::BGR: setChannelOrder( ImageIo::BGR ); break; default: setChannelOrder( ImageIo::CUSTOM ); // in case we don't find a match break; } }
void ImageTargetFileWic::setupPixelFormat( const GUID &guid ) { if( guid == GUID_WICPixelFormat24bppBGR ) { setChannelOrder( ImageIo::BGR ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 ); } else if( guid == GUID_WICPixelFormat24bppRGB ) { setChannelOrder( ImageIo::RGB ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 ); } else if( guid == GUID_WICPixelFormat32bppBGR ) { setChannelOrder( ImageIo::BGRX ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 ); } else if( guid == GUID_WICPixelFormat32bppBGRA ) { setChannelOrder( ImageIo::BGRA ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 ); } else if( guid == GUID_WICPixelFormat32bppPBGRA ) { setChannelOrder( ImageIo::BGRA ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 );// mIsPremultipliedAlpha = true; } else if( guid == GUID_WICPixelFormat48bppRGB ) { setChannelOrder( ImageIo::RGB ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT16 ); } else if( guid == GUID_WICPixelFormat64bppRGBA ) { setChannelOrder( ImageIo::RGBA ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT16 ); } else if( guid == GUID_WICPixelFormat64bppPRGBA ) { setChannelOrder( ImageIo::RGBA ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT16 ); // mIsPremultipliedAlpha = true; } else if( guid == GUID_WICPixelFormat128bppRGBFloat ) { setChannelOrder( ImageIo::RGB ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::FLOAT32 ); } else if( guid == GUID_WICPixelFormat8bppGray ) { setChannelOrder( ImageIo::Y ); setColorModel( ImageIo::CM_GRAY ); setDataType( ImageIo::UINT8 ); } else if( guid == GUID_WICPixelFormat16bppGray ) { setChannelOrder( ImageIo::Y ); setColorModel( ImageIo::CM_GRAY ); setDataType( ImageIo::UINT16 ); } else if( guid == GUID_WICPixelFormat32bppGrayFloat ) { setChannelOrder( ImageIo::Y ); setColorModel( ImageIo::CM_GRAY ); setDataType( ImageIo::FLOAT32 ); } else throw ImageIoExceptionFailedLoad(); int32_t bitsPerComponent; bool writingAlpha = hasAlpha(); bool isFloat = true; switch( getDataType() ) { case ImageIo::UINT8: bitsPerComponent = 8; isFloat = false; break; case ImageIo::UINT16: bitsPerComponent = 16; isFloat = false; break; default: bitsPerComponent = 32; isFloat = true; } uint8_t numChannels; switch( getColorModel() ) { case ImageIo::CM_GRAY: numChannels = ( writingAlpha ) ? 2 : 1; break; default: numChannels = ( writingAlpha ) ? 4 : 3; } int32_t bitsPerPixel = numChannels * bitsPerComponent; mRowBytes = ( mWidth * ( bitsPerPixel / 8 ) + 3 ) & ~3; return; }
// returns true if we need conversion bool ImageSourceFileWic::processFormat( const ::GUID &guid, ::GUID *convertGUID ) { if( ( guid == GUID_WICPixelFormat1bppIndexed ) || ( guid == GUID_WICPixelFormat2bppIndexed ) || ( guid == GUID_WICPixelFormat4bppIndexed ) || ( guid == GUID_WICPixelFormat8bppIndexed ) || ( guid == GUID_WICPixelFormat16bppBGR555 ) || ( guid == GUID_WICPixelFormat16bppBGR565 ) ) { setChannelOrder( ImageIo::RGB ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 ); *convertGUID = GUID_WICPixelFormat24bppRGB; return true; } else if( guid == GUID_WICPixelFormat24bppBGR ) { setChannelOrder( ImageIo::BGR ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 ); } else if( guid == GUID_WICPixelFormat24bppRGB ) { setChannelOrder( ImageIo::RGB ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 ); } else if( guid == GUID_WICPixelFormat32bppBGR ) { setChannelOrder( ImageIo::BGRX ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 ); } else if( guid == GUID_WICPixelFormat32bppBGRA ) { setChannelOrder( ImageIo::BGRA ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 ); } else if( guid == GUID_WICPixelFormat32bppPBGRA ) { setChannelOrder( ImageIo::BGRA ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 ); setPremultiplied( true ); } else if( guid == GUID_WICPixelFormat48bppRGB ) { setChannelOrder( ImageIo::RGB ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT16 ); } else if( guid == GUID_WICPixelFormat64bppRGBA ) { setChannelOrder( ImageIo::RGBA ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT16 ); } else if( guid == GUID_WICPixelFormat64bppPRGBA ) { setChannelOrder( ImageIo::RGBA ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT16 ); setPremultiplied( true ); } else if( guid == GUID_WICPixelFormat128bppRGBFloat ) { setChannelOrder( ImageIo::RGB ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::FLOAT32 ); } else if( guid == GUID_WICPixelFormat8bppGray ) { setChannelOrder( ImageIo::Y ); setColorModel( ImageIo::CM_GRAY ); setDataType( ImageIo::UINT8 ); } else if( guid == GUID_WICPixelFormat16bppGray ) { setChannelOrder( ImageIo::Y ); setColorModel( ImageIo::CM_GRAY ); setDataType( ImageIo::UINT16 ); } else if( guid == GUID_WICPixelFormat32bppGrayFloat ) { setChannelOrder( ImageIo::Y ); setColorModel( ImageIo::CM_GRAY ); setDataType( ImageIo::FLOAT32 ); } return false; }