virtual WriteResult writeImage(const osg::Image& image,std::ostream& fout,const osgDB::ReaderWriter::Options* options) const { bool ascii = (options && options->getOptionString().find("ascii")!=std::string::npos); if (ascii) { // ascii ppm format. fout<<"P3"<<std::endl; fout<<image.s()<<" "<<image.t()<<std::endl; fout<<"255"<<std::endl; for(int row = image.t()-1; row >= 0; --row) { const unsigned char* ptr = image.data(0,row); for(int col = 0; col < image.s(); ++col) { fout<<static_cast<int>(*(ptr++)); fout<<" "<<static_cast<int>(*(ptr++)); fout<<" "<<static_cast<int>(*(ptr++))<<" "; } fout<<std::endl; } } else { // binary ppm format fout<<"P6"<<std::endl; fout<<image.s()<<" "<<image.t()<<std::endl; fout<<"255"<<std::endl; for(int row = image.t()-1; row >= 0; --row) { const unsigned char* ptr = image.data(0,row); for(int col = 0; col < image.s(); ++col) { fout.put(*(ptr++)); fout.put(*(ptr++)); fout.put(*(ptr++)); } } } return WriteResult::FILE_SAVED; }
void DepthCallback::restore(osg::Image& src,string& filename,int w,int h) const { float * tmp= reinterpret_cast<float*>(src.data()); fstream fout; fout.open(filename,ios::out); for(int i=0;i<h;i++) { for(int j=0;j<w;j++) { fout<<tmp[i*w+j]<<" "; } fout<<endl; } fout.close(); }
// Convert RGB to BGRA : nvtt only accepts BGRA pixel format void NVTTProcessor::convertRGBToBGRA( std::vector<unsigned char>& outputData, const osg::Image& image ) { unsigned int n=0; for(int row=0; row<image.t(); ++row) { const unsigned char* data = image.data(0,row); for(int column=0; column<image.s(); ++column) { outputData[n] = data[column*3+2]; outputData[n+1] = data[column*3+1]; outputData[n+2] = data[column*3]; outputData[n+3] = 255; n+=4; } } }
void operator()(const osg::Image& image, const unsigned int) { frame_id++; QImage::Format qtFormat; if (image.getPixelFormat() == GL_BGR) qtFormat = QImage::Format_RGB888; else if (image.getPixelFormat() == GL_BGRA) qtFormat = QImage::Format_ARGB32; else if (image.getPixelFormat() == GL_RGB) qtFormat = QImage::Format_RGB888; else if (image.getPixelFormat() == GL_RGBA) qtFormat = QImage::Format_ARGB32; else throw std::runtime_error("cannot interpret osg-provided image format " + boost::lexical_cast<std::string>(image.getPixelFormat())); this->image = QImage(image.data(), image.s(), image.t(), qtFormat); }
/* Create a CGImageRef from osg::Image. * Code adapted from * http://developer.apple.com/samplecode/OpenGLScreenSnapshot/listing2.html */ CGImageRef CreateCGImageFromOSGData(const osg::Image& osg_image) { size_t image_width = osg_image.s(); size_t image_height = osg_image.t(); /* From Apple's header for CGBitmapContextCreate() * Each row of the bitmap consists of `bytesPerRow' bytes, which must be at * least `(width * bitsPerComponent * number of components + 7)/8' bytes. */ size_t target_bytes_per_row; CGColorSpaceRef color_space; CGBitmapInfo bitmap_info; /* From what I can figure out so far... * We need to create a CGContext connected to the data we want to save * and then call CGBitmapContextCreateImage() on that context to get * a CGImageRef. * However, OS X only allows 4-component image formats (e.g. RGBA) and not * just RGB for the RGB-based CGContext. So for a 24-bit image coming in, * we need to expand the data to 32-bit. * The easiest and fastest way to do that is through the vImage framework * which is part of the Accelerate framework. * Also, the osg::Image data coming in is inverted from what we want, so * we need to invert the image too. Since the osg::Image is const, * we don't want to touch the data, so again we turn to the vImage framework * and invert the data. */ vImage_Buffer vimage_buffer_in = { (void*)osg_image.data(), // need to override const, but we don't modify the data so it's safe image_height, image_width, osg_image.getRowSizeInBytes() }; void* out_image_data; vImage_Buffer vimage_buffer_out = { NULL, // will fill-in in switch image_height, image_width, 0 // will fill-in in switch }; vImage_Error vimage_error_flag; // FIXME: Do I want to use format, type, or internalFormat? switch(osg_image.getPixelFormat()) { case GL_LUMINANCE: { bitmap_info = kCGImageAlphaNone; target_bytes_per_row = (image_width * 8 + 7)/8; //color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray); color_space = CGColorSpaceCreateDeviceGray(); if(NULL == color_space) { return NULL; } // out_image_data = calloc(target_bytes_per_row, image_height); out_image_data = malloc(target_bytes_per_row * image_height); if(NULL == out_image_data) { OSG_WARN << "In CreateCGImageFromOSGData, malloc failed" << std::endl; CGColorSpaceRelease(color_space); return NULL; } vimage_buffer_out.data = out_image_data; vimage_buffer_out.rowBytes = target_bytes_per_row; // Now invert the image vimage_error_flag = vImageVerticalReflect_Planar8( &vimage_buffer_in, // since the osg_image is const... &vimage_buffer_out, // don't reuse the buffer kvImageNoFlags ); if(vimage_error_flag != kvImageNoError) { OSG_WARN << "In CreateCGImageFromOSGData for GL_LUMINANCE, vImageVerticalReflect_Planar8 failed with vImage Error Code: " << vimage_error_flag << std::endl; free(out_image_data); CGColorSpaceRelease(color_space); return NULL; } break; } case GL_ALPHA: { bitmap_info = kCGImageAlphaOnly; target_bytes_per_row = (image_width * 8 + 7)/8; // According to: // http://developer.apple.com/qa/qa2001/qa1037.html // colorSpace=NULL is for alpha only color_space = NULL; // out_image_data = calloc(target_bytes_per_row, image_height); out_image_data = malloc(target_bytes_per_row * image_height); if(NULL == out_image_data) { OSG_WARN << "In CreateCGImageFromOSGData, malloc failed" << std::endl; return NULL; } vimage_buffer_out.data = out_image_data; vimage_buffer_out.rowBytes = target_bytes_per_row; // Now invert the image vimage_error_flag = vImageVerticalReflect_Planar8( &vimage_buffer_in, // since the osg_image is const... &vimage_buffer_out, // don't reuse the buffer kvImageNoFlags ); if(vimage_error_flag != kvImageNoError) { OSG_WARN << "In CreateCGImageFromOSGData for GL_ALPHA, vImageVerticalReflect_Planar8 failed with vImage Error Code: " << vimage_error_flag << std::endl; free(out_image_data); return NULL; } break; } /* case GL_LUMINANCE_ALPHA: { // I don't know if we can support this. // The qa1037 doesn't show both gray+alpha. break; } */ case GL_RGB: { bitmap_info = kCGImageAlphaNoneSkipFirst; target_bytes_per_row = (image_width * 8 * 4 + 7)/8; //color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); color_space = CGColorSpaceCreateDeviceRGB(); if(NULL == color_space) { OSG_WARN << "In CreateCGImageFromOSGData, CGColorSpaceCreateWithName failed" << std::endl; return NULL; } // out_image_data = calloc(target_bytes_per_row, image_height); out_image_data = malloc(target_bytes_per_row * image_height); if(NULL == out_image_data) { OSG_WARN << "In CreateCGImageFromOSGData, malloc failed" << std::endl; CGColorSpaceRelease(color_space); return NULL; } // Use vImage to get an RGB buffer into ARGB. vimage_buffer_out.data = out_image_data; vimage_buffer_out.rowBytes = target_bytes_per_row; vimage_error_flag = vImageConvert_RGB888toARGB8888( &vimage_buffer_in, NULL, // we don't have a buffer containing alpha values 255, // The alpha value we want given to all pixels since we don't have a buffer &vimage_buffer_out, 0, // premultiply? kvImageNoFlags // Only responds to kvImageDoNotTile, but I think we want tiling/threading ); if(vimage_error_flag != kvImageNoError) { OSG_WARN << "In CreateCGImageFromOSGData, vImageConvert_RGB888toARGB8888 failed with vImage Error Code: " << vimage_error_flag << std::endl; free(out_image_data); CGColorSpaceRelease(color_space); return NULL; } // Now invert the image vimage_error_flag = vImageVerticalReflect_ARGB8888( &vimage_buffer_out, &vimage_buffer_out, // reuse the same buffer kvImageNoFlags ); if(vimage_error_flag != kvImageNoError) { OSG_WARN << "In CreateCGImageFromOSGData, vImageAffineWarp_ARGB8888 failed with vImage Error Code: " << vimage_error_flag << std::endl; free(out_image_data); CGColorSpaceRelease(color_space); return NULL; } break; } case GL_RGBA: { bitmap_info = kCGImageAlphaPremultipliedLast; target_bytes_per_row = osg_image.getRowSizeInBytes(); //color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); color_space = CGColorSpaceCreateDeviceRGB(); if(NULL == color_space) { OSG_WARN << "In CreateCGImageFromOSGData, CGColorSpaceCreateWithName failed" << std::endl; return NULL; } // out_image_data = calloc(target_bytes_per_row, image_height); out_image_data = malloc(target_bytes_per_row * image_height); if(NULL == out_image_data) { OSG_WARN << "In CreateCGImageFromOSGData, malloc failed" << std::endl; CGColorSpaceRelease(color_space); return NULL; } vimage_buffer_out.data = out_image_data; vimage_buffer_out.rowBytes = target_bytes_per_row; // Invert the image vimage_error_flag = vImageVerticalReflect_ARGB8888( &vimage_buffer_in, // since the osg_image is const... &vimage_buffer_out, // don't reuse the buffer kvImageNoFlags ); if(vimage_error_flag != kvImageNoError) { OSG_WARN << "In CreateCGImageFromOSGData, vImageAffineWarp_ARGB8888 failed with vImage Error Code: " << vimage_error_flag << std::endl; free(out_image_data); CGColorSpaceRelease(color_space); return NULL; } break; } case GL_BGRA: { if(GL_UNSIGNED_INT_8_8_8_8_REV == osg_image.getDataType()) { #if __BIG_ENDIAN__ bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big; /* XRGB Big Endian */ #else bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little; /* XRGB Little Endian */ #endif } else { // FIXME: Don't know how to handle this case bitmap_info = kCGImageAlphaPremultipliedLast; } target_bytes_per_row = osg_image.getRowSizeInBytes(); //color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); color_space = CGColorSpaceCreateDeviceRGB(); if(NULL == color_space) { OSG_WARN << "In CreateCGImageFromOSGData, CGColorSpaceCreateWithName failed" << std::endl; return NULL; } // out_image_data = calloc(target_bytes_per_row, image_height); out_image_data = malloc(target_bytes_per_row * image_height); if(NULL == out_image_data) { OSG_WARN << "In CreateCGImageFromOSGData, malloc failed" << std::endl; CGColorSpaceRelease(color_space); return NULL; } vimage_buffer_out.data = out_image_data; vimage_buffer_out.rowBytes = target_bytes_per_row; // Invert the image vimage_error_flag = vImageVerticalReflect_ARGB8888( &vimage_buffer_in, // since the osg_image is const... &vimage_buffer_out, // don't reuse the buffer kvImageNoFlags ); if(vimage_error_flag != kvImageNoError) { OSG_WARN << "In CreateCGImageFromOSGData, vImageAffineWarp_ARGB8888 failed with vImage Error Code: " << vimage_error_flag << std::endl; free(out_image_data); CGColorSpaceRelease(color_space); return NULL; } break; } // FIXME: Handle other cases. // Use vImagePermuteChannels_ARGB8888 to swizzle bytes default: { OSG_WARN << "In CreateCGImageFromOSGData: Sorry support for this format is not implemented." << std::endl; return NULL; break; } } CGContextRef bitmap_context = CGBitmapContextCreate( vimage_buffer_out.data, vimage_buffer_out.width, vimage_buffer_out.height, 8, vimage_buffer_out.rowBytes, color_space, bitmap_info ); /* Done with color space */ CGColorSpaceRelease(color_space); if(NULL == bitmap_context) { free(out_image_data); return NULL; } /* Make an image out of our bitmap; does a cheap vm_copy of the bitmap */ CGImageRef image_ref = CGBitmapContextCreateImage(bitmap_context); /* Done with data */ free(out_image_data); /* Done with bitmap_context */ CGContextRelease(bitmap_context); return image_ref; }
WriteResult::WriteStatus writeTIFStream(std::ostream& fout, const osg::Image& img, const osgDB::ReaderWriter::Options* options) const { int compressionType = COMPRESSION_PACKBITS; if (options) { std::istringstream iss(options->getOptionString()); std::string opt; while (iss >> opt) { opt = osgDB::convertToLowerCase(opt); std::size_t eqInd = opt.find("="); if (opt.substr(0, eqInd) == "tiff_compression") { std::string compressTypeOpt; compressTypeOpt = opt.substr(eqInd + 1); compressTypeOpt = osgDB::convertToLowerCase(compressTypeOpt); if (compressTypeOpt == "packbits") { compressionType = COMPRESSION_PACKBITS; } else if (compressTypeOpt == "lzw") { compressionType = COMPRESSION_LZW; } else if (compressTypeOpt == "jpeg") { compressionType = COMPRESSION_JPEG; } } } } //Code is based from the following article on CodeProject.com //http://www.codeproject.com/bitmap/BitmapsToTiffs.asp TIFF *image; int samplesPerPixel; int bitsPerSample; uint16 photometric; image = TIFFClientOpen("outputstream", "w", (thandle_t)&fout, libtiffOStreamReadProc, //Custom read function libtiffOStreamWriteProc, //Custom write function libtiffOStreamSeekProc, //Custom seek function libtiffStreamCloseProc, //Custom close function libtiffOStreamSizeProc, //Custom size function libtiffStreamMapProc, //Custom map function libtiffStreamUnmapProc); //Custom unmap function if(image == NULL) { return WriteResult::ERROR_IN_WRITING_FILE; } switch(img.getPixelFormat()) { case GL_DEPTH_COMPONENT: case GL_LUMINANCE: case GL_ALPHA: photometric = PHOTOMETRIC_MINISBLACK; samplesPerPixel = 1; break; case GL_LUMINANCE_ALPHA: photometric = PHOTOMETRIC_MINISBLACK; samplesPerPixel = 2; break; case GL_RGB: photometric = PHOTOMETRIC_RGB; samplesPerPixel = 3; break; case GL_RGBA: photometric = PHOTOMETRIC_RGB; samplesPerPixel = 4; break; default: return WriteResult::ERROR_IN_WRITING_FILE; break; } switch(img.getDataType()){ case GL_FLOAT: TIFFSetField(image, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, 1); bitsPerSample = 32; break; case GL_SHORT: TIFFSetField(image, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT); bitsPerSample = 16; break; default: bitsPerSample = 8; break; } TIFFSetField(image, TIFFTAG_IMAGEWIDTH,img.s()); TIFFSetField(image, TIFFTAG_IMAGELENGTH,img.t()); TIFFSetField(image, TIFFTAG_BITSPERSAMPLE,bitsPerSample); TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL,samplesPerPixel); TIFFSetField(image, TIFFTAG_PHOTOMETRIC, photometric); TIFFSetField(image, TIFFTAG_COMPRESSION, compressionType); TIFFSetField(image, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB); TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); //uint32 rowsperstrip = TIFFDefaultStripSize(image, -1); //TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, rowsperstrip); // Write the information to the file for(int i = 0; i < img.t(); ++i) { TIFFWriteScanline(image,(tdata_t)img.data(0,img.t()-i-1),i,0); } // Close the file TIFFClose(image); return WriteResult::FILE_SAVED; }
WriteResult::WriteStatus writeTIFStream(std::ostream& fout, const osg::Image& img) const { //Code is based from the following article on CodeProject.com //http://www.codeproject.com/bitmap/BitmapsToTiffs.asp TIFF *image; int samplesPerPixel; int bitsPerSample; uint16 photometric; image = TIFFClientOpen("outputstream", "w", (thandle_t)&fout, libtiffOStreamReadProc, //Custom read function libtiffOStreamWriteProc, //Custom write function libtiffOStreamSeekProc, //Custom seek function libtiffStreamCloseProc, //Custom close function libtiffOStreamSizeProc, //Custom size function libtiffStreamMapProc, //Custom map function libtiffStreamUnmapProc); //Custom unmap function if(image == NULL) { return WriteResult::ERROR_IN_WRITING_FILE; } switch(img.getPixelFormat()) { case GL_LUMINANCE: case GL_ALPHA: photometric = PHOTOMETRIC_MINISBLACK; samplesPerPixel = 1; break; case GL_LUMINANCE_ALPHA: photometric = PHOTOMETRIC_MINISBLACK; samplesPerPixel = 2; break; case GL_RGB: photometric = PHOTOMETRIC_RGB; samplesPerPixel = 3; break; case GL_RGBA: photometric = PHOTOMETRIC_RGB; samplesPerPixel = 4; break; default: return WriteResult::ERROR_IN_WRITING_FILE; break; } switch(img.getDataType()){ case GL_FLOAT: TIFFSetField(image, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, 1); bitsPerSample = 32; break; default: bitsPerSample = 8; break; } TIFFSetField(image, TIFFTAG_IMAGEWIDTH,img.s()); TIFFSetField(image, TIFFTAG_IMAGELENGTH,img.t()); TIFFSetField(image, TIFFTAG_BITSPERSAMPLE,bitsPerSample); TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL,samplesPerPixel); TIFFSetField(image, TIFFTAG_PHOTOMETRIC, photometric); TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_PACKBITS); TIFFSetField(image, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB); TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); //uint32 rowsperstrip = TIFFDefaultStripSize(image, -1); //TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, rowsperstrip); // Write the information to the file for(int i = 0; i < img.t(); ++i) { TIFFWriteScanline(image,(tdata_t)img.data(0,img.t()-i-1),i,0); } // Close the file TIFFClose(image); return WriteResult::FILE_SAVED; }
WriteResult writeRGBStream(const osg::Image& img, std::ostream &fout, const std::string& name) const { rawImageRec raw; raw.imagic = 0732; GLenum dataType = img.getDataType(); raw.type = dataType == GL_UNSIGNED_BYTE ? 1 : dataType == GL_BYTE ? 1 : dataType == GL_BITMAP ? 1 : dataType == GL_UNSIGNED_SHORT ? 2 : dataType == GL_SHORT ? 2 : dataType == GL_UNSIGNED_INT ? 4 : dataType == GL_INT ? 4 : dataType == GL_FLOAT ? 4 : dataType == GL_UNSIGNED_BYTE_3_3_2 ? 1 : dataType == GL_UNSIGNED_BYTE_2_3_3_REV ? 1 : dataType == GL_UNSIGNED_SHORT_5_6_5 ? 2 : dataType == GL_UNSIGNED_SHORT_5_6_5_REV ? 2 : dataType == GL_UNSIGNED_SHORT_4_4_4_4 ? 2 : dataType == GL_UNSIGNED_SHORT_4_4_4_4_REV ? 2 : dataType == GL_UNSIGNED_SHORT_5_5_5_1 ? 2 : dataType == GL_UNSIGNED_SHORT_1_5_5_5_REV ? 2 : dataType == GL_UNSIGNED_INT_8_8_8_8 ? 4 : dataType == GL_UNSIGNED_INT_8_8_8_8_REV ? 4 : dataType == GL_UNSIGNED_INT_10_10_10_2 ? 4 : dataType == GL_UNSIGNED_INT_2_10_10_10_REV ? 4 : 4; GLenum pixelFormat = img.getPixelFormat(); raw.dim = 3; raw.sizeX = img.s(); raw.sizeY = img.t(); raw.sizeZ = pixelFormat == GL_COLOR_INDEX? 1 : pixelFormat == GL_RED? 1 : pixelFormat == GL_GREEN? 1 : pixelFormat == GL_BLUE? 1 : pixelFormat == GL_ALPHA? 1 : pixelFormat == GL_RGB? 3 : pixelFormat == GL_BGR ? 3 : pixelFormat == GL_RGBA? 4 : pixelFormat == GL_BGRA? 4 : pixelFormat == GL_LUMINANCE? 1 : pixelFormat == GL_LUMINANCE_ALPHA ? 2 : 1; raw.min = 0; raw.max = 0xFF; raw.wasteBytes = 0; strncpy( raw.name, name.c_str(), 80); raw.colorMap = 0; raw.bpc = (img.getPixelSizeInBits()/raw.sizeZ)/8; int isize = img.getImageSizeInBytes(); unsigned char *buffer = new unsigned char[isize]; if(raw.bpc == 1) { unsigned char *dptr = buffer; int i, j; for( i = 0; i < raw.sizeZ; ++i ) { const unsigned char *ptr = img.data(); ptr += i; for( j = 0; j < isize/raw.sizeZ; ++j ) { *(dptr++) = *ptr; ptr += raw.sizeZ; } } } else { // bpc == 2 unsigned short *dptr = reinterpret_cast<unsigned short*>(buffer); int i, j; for( i = 0; i < raw.sizeZ; ++i ) { const unsigned short *ptr = reinterpret_cast<const unsigned short*>(img.data()); ptr += i; for( j = 0; j < isize/(raw.sizeZ*2); ++j ) { *dptr = *ptr; ConvertShort(dptr++, 1); ptr += raw.sizeZ; } } } if( raw.needsBytesSwapped() ) raw.swapBytes(); /* swapBytes( raw.imagic ); swapBytes( raw.type ); swapBytes( raw.dim ); swapBytes( raw.sizeX ); swapBytes( raw.sizeY ); swapBytes( raw.sizeZ ); swapBytes( raw.min ); swapBytes( raw.max ); swapBytes( raw.colorMap ); */ char pad[512 - sizeof(rawImageRec)]; memset( pad, 0, sizeof(pad)); fout.write((const char*)&raw,sizeof(rawImageRec)); fout.write((const char*)pad,sizeof(pad)); fout.write((const char*)buffer,isize); delete [] buffer; return WriteResult::FILE_SAVED; }
bool writeEXRStream(const osg::Image &img, std::ostream& fout, const std::string &fileName) const { bool writeOK = true; //Obtain data from texture int width = img.s(); int height = img.t(); unsigned int pixelFormat = img.getPixelFormat(); int numComponents = img.computeNumComponents(pixelFormat); unsigned int dataType = img.getDataType(); //Validates image data //if numbers of components matches if (!( numComponents == 3 || numComponents == 4)) { writeOK = false; return false; } if (!( dataType == GL_HALF_FLOAT_ARB || dataType == GL_FLOAT)) { writeOK = false; return false; } //Create a stream to save to C_OStream outStream(&fout); //Copy data from texture to rgba pixel format Array2D<Rgba> outPixels(height,width); //If texture is half format if (dataType == GL_HALF_FLOAT_ARB) { half* pOut = (half*) img.data(); for (long i = height-1; i >= 0; i--) { for (long j = 0 ; j < width; j++) { outPixels[i][j].r = (*pOut); pOut++; outPixels[i][j].g = (*pOut); pOut++; outPixels[i][j].b = (*pOut); pOut++; if (numComponents >= 4) { outPixels[i][j].a = (*pOut); pOut++; } else { outPixels[i][j].a = 1.0f; } } } } else if (dataType == GL_FLOAT) { float* pOut = (float*) img.data(); for (long i = height-1; i >= 0; i--) { for (long j = 0 ; j < width; j++) { outPixels[i][j].r = half(*pOut); pOut++; outPixels[i][j].g = half(*pOut); pOut++; outPixels[i][j].b = half(*pOut); pOut++; if (numComponents >= 4) { outPixels[i][j].a = half(*pOut); pOut++; } else { outPixels[i][j].a = 1.0f; } } } } else { //If texture format not supported return false; } try { //Write to stream Header outHeader(width, height); RgbaOutputFile rgbaFile (outStream, outHeader, WRITE_RGBA); rgbaFile.setFrameBuffer ((&outPixels)[0][0], 1, width); rgbaFile.writePixels (height); } catch( char * str ) { writeOK = false; } return writeOK; }
WriteResult writeImage(const osg::Image& img, std::ostream& fout, const Options* options) const { if (!img.isDataContiguous()) { OSG_WARN<<"Warning: Writing of image data, that is non contiguous, is not supported by JPEG2000 plugin."<<std::endl; return WriteResult::ERROR_IN_WRITING_FILE; } jas_image_cmptparm_t cmptparms[4]; jas_image_cmptparm_t *cmptparm; int internalFormat = osg::Image::computeNumComponents(img.getPixelFormat()); jas_stream_t* mem = jas_stream_memopen((char*)img.data(), internalFormat*img.s()*img.t()); /* Create an image of the correct size. */ jas_image_t* jimage; int i; for (i = 0, cmptparm = cmptparms; i < internalFormat; ++i, ++cmptparm) { cmptparm->tlx = 0; cmptparm->tly = 0; cmptparm->hstep = 1; cmptparm->vstep = 1; cmptparm->width = img.s(); cmptparm->height = img.t(); cmptparm->prec = 8; cmptparm->sgnd = 0; } if (!(jimage = jas_image_create(internalFormat, cmptparms, JAS_CLRSPC_UNKNOWN))) { return WriteResult::ERROR_IN_WRITING_FILE; } if(internalFormat == 1) { jas_image_setclrspc(jimage, JAS_CLRSPC_SGRAY); jas_image_setcmpttype(jimage, 0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y)); } else if(internalFormat == 2) { jas_image_setclrspc(jimage, JAS_CLRSPC_SGRAY); jas_image_setcmpttype(jimage, 0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y)); jas_image_setcmpttype(jimage, 1, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_OPACITY)); } else if(internalFormat == 3) { jas_image_setclrspc(jimage, JAS_CLRSPC_SRGB); jas_image_setcmpttype(jimage, 0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R)); jas_image_setcmpttype(jimage, 1, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G)); jas_image_setcmpttype(jimage, 2, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B)); } else if(internalFormat == 4) { jas_image_setclrspc(jimage, JAS_CLRSPC_SRGB); jas_image_setcmpttype(jimage, 0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R)); jas_image_setcmpttype(jimage, 1, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G)); jas_image_setcmpttype(jimage, 2, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B)); jas_image_setcmpttype(jimage, 3, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_OPACITY)); } getdata(mem, jimage); jas_stream_t* out = jas_stream_memopen(0, 0); if (!out) return WriteResult::ERROR_IN_WRITING_FILE; char* opt = 0; if(options) { opt = new char[options->getOptionString().size() + 1]; strcpy(opt, options->getOptionString().c_str()); } jas_image_encode(jimage, out, _fmt_jp2, opt); if(opt) delete[] opt; jas_stream_flush(out); // now the encoded jp2 image resides in the out->buf_ member with size out->len_ we now need to stream it to a std::ostream jas_stream_memobj_t* obj = (jas_stream_memobj_t*) out->obj_; fout.write((char*)obj->buf_, obj->len_); fout << std::flush; jas_stream_close(out); jas_image_destroy(jimage); return WriteResult::FILE_SAVED; }
virtual WriteResult writeImage(const osg::Image &img,const std::string& fileName, const osgDB::ReaderWriter::Options* options) const { std::string ext = osgDB::getFileExtension(fileName); if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED; if (!img.isDataContiguous()) { OSG_WARN<<"Warning: Writing of image data, that is non contiguous, is not supported by JPEG2000 plugin."<<std::endl; return WriteResult::ERROR_IN_WRITING_FILE; } jas_image_cmptparm_t cmptparms[4]; jas_image_cmptparm_t *cmptparm; int internalFormat = osg::Image::computeNumComponents(img.getPixelFormat()); jas_stream_t* mem = jas_stream_memopen((char*)img.data(), internalFormat*img.s()*img.t()); /* Create an image of the correct size. */ jas_image_t* jimage; int i; for (i = 0, cmptparm = cmptparms; i < internalFormat; ++i, ++cmptparm) { cmptparm->tlx = 0; cmptparm->tly = 0; cmptparm->hstep = 1; cmptparm->vstep = 1; cmptparm->width = img.s(); cmptparm->height = img.t(); cmptparm->prec = 8; cmptparm->sgnd = 0; } if (!(jimage = jas_image_create(internalFormat, cmptparms, JAS_CLRSPC_UNKNOWN))) { return WriteResult::ERROR_IN_WRITING_FILE; } if(internalFormat == 1) { jas_image_setclrspc(jimage, JAS_CLRSPC_GENGRAY); jas_image_setcmpttype(jimage, 0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y)); } else if(internalFormat == 2) { jas_image_setclrspc(jimage, JAS_CLRSPC_GENGRAY); jas_image_setcmpttype(jimage, 0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y)); jas_image_setcmpttype(jimage, 1, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_OPACITY)); } else if(internalFormat == 3) { jas_image_setclrspc(jimage, JAS_CLRSPC_SRGB); jas_image_setcmpttype(jimage, 0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R)); jas_image_setcmpttype(jimage, 1, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G)); jas_image_setcmpttype(jimage, 2, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B)); } else if(internalFormat == 4) { jas_image_setclrspc(jimage, JAS_CLRSPC_SRGB); jas_image_setcmpttype(jimage, 0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R)); jas_image_setcmpttype(jimage, 1, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G)); jas_image_setcmpttype(jimage, 2, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B)); jas_image_setcmpttype(jimage, 3, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_OPACITY)); } getdata(mem, jimage); FILE * fileHandle = osgDB::fopen(fileName.c_str(), "wb"); if (!fileHandle) { return WriteResult::ERROR_IN_WRITING_FILE; } jas_stream_t* out = jas_stream_freopen(fileName.c_str(), "wb", fileHandle); // Replacement for jas_stream_fopen() to be able to support UTF8 if (!out) { fclose(fileHandle); return WriteResult::ERROR_IN_WRITING_FILE; } char* opt = 0; if(options) { opt = new char[options->getOptionString().size() + 1]; strcpy(opt, options->getOptionString().c_str()); } jas_image_encode(jimage, out, _fmt_jp2, opt); if(opt) delete[] opt; jas_stream_flush(out); jas_stream_close(out); jas_image_destroy(jimage); fclose(fileHandle); return WriteResult::FILE_SAVED; }