123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595 |
- #include <sstream>
- #include "core/image/ImageFile.h"
- #include "core/image/Convert.h"
- #ifdef NICE_USELIB_LIMUN_IOCOMPRESSION
- #include "iocompression/pipestream.h"
- #include "iocompression/magic.h"
- #endif
- #ifdef NICE_USELIB_LIBMAGICK
- #include <Magick++.h>
- #endif
- namespace NICE {
- ImageFile::ImageFile(const std::string &filename, Format type)
- {
- this->filename=filename;
- if(type==FormatUnknown)
- {
- fileformat=ImageFile::name2Format(filename);
- }
- else
- {
- fileformat=type;
- }
- datapos=0;
- }
- ImageFile::ImageFile()
- {
- filename = "";
- fileformat = FormatUnknown;
- datapos=0;
- }
- ImageFile::ImageFile(const ImageFile& ex)
- {
- *this=ex;
- }
- ImageFile& ImageFile::operator=(const ImageFile& ex)
- {
- filename=ex.filename;
- fileformat=ex.fileformat;
- fileheader=ex.fileheader;
- datapos=ex.datapos;
- return *this;
- }
- ImageFile::~ImageFile()
- {
- }
- #include <iostream>
- #ifdef NICE_USELIB_PNG
- template<>
- void ImageFile::readerPNG(GrayColorImageCommonImplementationT<Ipp32f> *image)
- {
- switch(image->channels())
- {
- case 1:
- {
- Image buffer;
- readerPNG(&buffer);
- if(image->widthInline()!=buffer.width() || image->heightInline()!=buffer.height()) {
- image->resize(buffer.width(), buffer.height());
- }
- grayToFloat(buffer,dynamic_cast<ImageT<Ipp32f>* >(image));
- break;
- }
- case 3:
- {
- ColorImage buffer;
- readerPNG(&buffer);
- if(image->widthInline()!=buffer.width() || image->heightInline()!=buffer.height()) {
- image->resize(buffer.width(), buffer.height());
- }
- convertBitDepth(buffer,dynamic_cast<ColorImageT<Ipp32f>* >(image));
- break;
- }
- default: fthrow(ImageException,"No or invalid color image->channels()");
- break;
- }
- }
- #endif
- #ifdef NICE_USELIB_LIBMAGICK
- template<>
- void ImageFile::readerMagick(GrayColorImageCommonImplementationT<unsigned char> *image)
- {
- Magick::Image magick_image;
- try {
- magick_image.read ( filename );
- } catch ( Magick::Warning &error) {
- std::cerr << "libMagick++ warning: " << error.what() << std::endl;
- }
-
- if(image->widthInline()!=(int)magick_image.baseColumns() || image->heightInline()!=(int)magick_image.baseRows()
- || image->getMemoryLayout() != GrayColorImageCommonImplementation::noAlignment )
- image->resize ( magick_image.baseColumns(), magick_image.baseRows(), GrayColorImageCommonImplementation::noAlignment );
- if ( image->channels() == 1 ) {
-
- magick_image.type( Magick::GrayscaleType );
- magick_image.write ( 0, 0, magick_image.baseColumns(), magick_image.baseRows(),
- "R", Magick::CharPixel, image->getPixelPointer() );
- } else {
- magick_image.write ( 0, 0, magick_image.baseColumns(), magick_image.baseRows(),
- "RGB", Magick::CharPixel, image->getPixelPointer() );
- }
-
- }
- template<>
- void ImageFile::writerMagick(const GrayColorImageCommonImplementationT<unsigned char> *image) const
- {
- if ( image->channels() == 1 )
- {
- Magick::Image magick_image;
-
- if ( image->rowStepsize() != image->width() )
- {
-
-
-
-
-
-
- ImageT<unsigned char> image_noalignment;
-
- image_noalignment.copyFrom ( *image, GrayColorImageCommonImplementation::noAlignment );
-
-
-
- Magick::Blob blob ( image_noalignment.getPixelPointer(), image_noalignment.width()*image_noalignment.height() );
- magick_image.magick ("GRAY");
- magick_image.read ( blob, Magick::Geometry ( image_noalignment.width(), image_noalignment.height() ), 8 );
- magick_image.write ( filename );
- }
- else
- {
- Magick::Blob blob ( image->getPixelPointer(), image->width()*image->height() );
-
- magick_image.magick ("GRAY");
- magick_image.read ( blob, Magick::Geometry ( image->width(), image->height() ), 8 );
-
- magick_image.write ( filename );
- }
- }
- else
- {
-
- if ( image->rowStepsize() != image->width() )
- {
- ColorImageT<unsigned char> image_noalignment;
-
- image_noalignment.copyFrom ( *image, GrayColorImageCommonImplementation::noAlignment );
- Magick::Image magick_image ( image_noalignment.width(), image_noalignment.height(),
- "RGB", Magick::CharPixel, image_noalignment.getPixelPointer() );
-
- std::string pngEnding ( ".png" );
-
-
-
-
- if ( filename.compare( filename.length() - pngEnding.length(), pngEnding.length(), pngEnding) == 0)
- {
- magick_image.defineValue( "png", "bit-depth", "8");
- magick_image.defineValue( "png", "format", "png8");
- }
-
- magick_image.write ( filename );
- }
- else
- {
-
- Magick::Image magick_image ( image->width(), image->height(),
- "RGB", Magick::CharPixel, image->getPixelPointer() );
-
- std::string pngEnding ( ".png" );
-
-
-
-
- if ( filename.compare( filename.length() - pngEnding.length(), pngEnding.length(), pngEnding) == 0)
- {
- magick_image.defineValue( "png", "bit-depth", "8");
- magick_image.defineValue( "png", "format", "png8");
- }
-
- magick_image.write ( filename );
- }
- }
- }
- #endif
- ImageFile::Format ImageFile::name2Format(const std::string &filename)
- {
- std::string magic;
- #ifdef NICE_USELIB_LIMUN_IOCOMPRESSION
- magic=magicString(filename);
- if(magic!="ERROR")
- {
- if(magic=="Netpbm PGM \"rawbits\" image data")
- return ImageFile::PGM_RAW;
- if(magic=="Netpbm PPM \"rawbits\" image data")
- return ImageFile::PPM_RAW;
- if(magic=="PNG image data")
- return ImageFile::PNG;
- if(magic=="JPG image data")
- return ImageFile::JPG;
- };
- #endif
- int pos=filename.find_last_of('.');
- if(pos==std::string::npos)
- return ImageFile::FormatUnknown;
- magic=filename.substr(pos);
- if(magic==".pgm" || magic==".PGM")
- return ImageFile::PGM_RAW;
- if(magic==".ppm" || magic==".PPM")
- return ImageFile::PPM_RAW;
- if(magic==".png" || magic==".PNG")
- return ImageFile::PNG;
- if(magic==".jpg" || magic==".JPG")
- return ImageFile::JPG;
- return ImageFile::FormatUnknown;
- }
- std::string ImageFile::getComment()
- {
- if(fileformat==FormatUnknown) {
- fileformat=ImageFile::name2Format(filename);
- }
- std::string comment="";
- #ifdef NICE_USELIB_LIMUN_IOCOMPRESSION
- std::string cmdstring="identify -format \"\%c\" ";
- cmdstring+=filename;
- ipipestream cmd(cmdstring.c_str());
- while(!cmd.eof()) {
- std::string line;
- getline(cmd,line);
- comment += line;
- }
- #endif
- return comment;
- }
- bool ImageFile::isGray() const
- {
- #ifdef NICE_USELIB_LIMUN_IOCOMPRESSION
- std::string cmdstring="identify -ping ";
- cmdstring+=filename;
- cmdstring+= "| cut -d' ' -f 4";
- ipipestream cmd(cmdstring.c_str());
- while(!cmd.eof()) {
- std::string line;
- getline(cmd,line);
- if(line=="PseudoClass")
- return true;
- }
- #endif
- return false;
- }
- uint ImageFile::width()
- {
- if ( fileheader.width < 0 )
- getMyHeader();
- if ( fileheader.width < 0 )
- fthrow(Exception, "Negative image width found in file header.");
-
- return (uint)fileheader.width;
- }
- uint ImageFile::height()
- {
- if ( fileheader.height < 0 )
- getMyHeader();
- if ( fileheader.height < 0 )
- fthrow(Exception, "Negative image width found in file header.");
-
- return (uint)fileheader.height;
- }
- const ImageFile::Header &ImageFile::getHeader()
- {
- getMyHeader();
- return fileheader;
- }
- void ImageFile::getMyHeader()
- {
- if(fileformat==FormatUnknown) {
- fileformat=ImageFile::name2Format(filename);
- }
- if(static_cast<int>(fileformat)>0 && static_cast<int>(fileformat)<8) {
- getPXMHeader();
- #ifdef NICE_USELIB_PNG
- } else if ( fileformat == ImageFile::PNG ) {
- getPNGHeader();
- #endif
- #ifdef NICE_USELIB_JPG
- } else if ( fileformat == ImageFile::JPG ) {
- getJPGHeader();
- #endif
- } else {
- #ifdef NICE_USELIB_LIBMAGICK
- MagickCore::ImageInfo *image_info=CloneImageInfo((MagickCore::ImageInfo *) NULL);
- strcpy(image_info->filename, filename.c_str());
- image_info->ping=MagickCore::MagickBooleanType(1);
-
- MagickCore::ExceptionInfo exc_info;
- GetExceptionInfo(&exc_info);
-
- MagickCore::Image *image=MagickCore::PingImage(image_info, &exc_info);
-
- fileheader.width = image->columns;
- fileheader.height = image->rows;
- MagickCore::DestroyImage(image);
- MagickCore::DestroyImageInfo(image_info);
- #else
- fthrow(ImageException,"Not implemented without Libmagick");
- #endif
- }
- }
- void ImageFile::getPXMHeader() {
- using namespace std;
- ifstream file(filename.c_str(), ios::binary);
-
- if(!file.good()) {
- fthrow(ImageException,string("getPXMHeader: Cannot open ") + filename);
- }
- char val;
- file.get(val);
- if(val!='P') {
- file.putback(val);
- fileformat=ImageFile::FormatUnknown;
- }
- file.get(val);
- if(val>'0' && val<'8') {
- fileformat=static_cast<ImageFile::Format>(val-'0');
- }
- if(fileformat==PPM_IMAGE_TEXT || fileformat==PPM_RAW)
- fileheader.channel=3;
- else
- fileheader.channel=1;
- int values=3;
- if(fileformat==PBM_IMAGE_TEXT || fileformat==PBM_RAW) {
- values=2;
- fileheader.bitdepth=1;
- }
- int status=0;
- int i=0, num=0;
- const int bsize = 1024;
- char buffer[bsize];
- while (file.good()&&num<values) {
- file.get(val);
- if(val=='#') {
- while (file.good() && val!='\n') {
- file.get(val);
- }
- continue;
- }
- if(val>='0'&& val<='9') {
- status=1;
- buffer[i++]=val;
- } else if(status==1) {
- num++;
- buffer[i++]=' ';
- status=0;
- }
- }
- datapos = file.tellg();
- buffer[i]=0;
- std::stringstream stream;
- stream << buffer;
- int maxval;
- if(values==3)
- stream >> fileheader.width >> fileheader.height >> maxval;
- else
- stream >> fileheader.width >> fileheader.height;
- if(maxval<256)
- fileheader.bitdepth=8;
- else if (maxval<65536)
- fileheader.bitdepth=16;
- else
- fileformat=ImageFile::FormatUnknown;
- }
- #ifdef NICE_USELIB_PNG
- void ImageFile::getPNGHeader ()
- {
- FILE* pFile;
-
- if ((pFile = fopen(filename.c_str(), "rb")) == NULL) {
- fthrow(ImageException,"ImageFile::getPNGHeader: Cannot open " + filename);
- }
-
- const int headersize=8;
- png_byte header[headersize];
- fread(header, 1, headersize, pFile);
- if (png_sig_cmp(header, 0, headersize)) {
- fclose(pFile);
- fthrow(ImageException,"Image is not a PNG file.");
- }
-
- png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- if (!png_ptr) {
- fclose(pFile);
- fthrow(ImageException,"png_create_read_struct failed");
- }
- png_infop info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr) {
- fclose(pFile);
- fthrow(ImageException,"png_create_info_struct failed");
- }
- if (setjmp(png_jmpbuf(png_ptr))) {
- fclose(pFile);
- fthrow(ImageException,"Error during init_io");
- }
- png_init_io(png_ptr, pFile);
- png_set_sig_bytes(png_ptr, headersize);
- png_read_info(png_ptr, info_ptr);
- fileheader.width = info_ptr->width;
- fileheader.height = info_ptr->height;
- fileheader.bitdepth = info_ptr->bit_depth;
-
- png_byte color_type = info_ptr->color_type;
- if ( color_type == PNG_COLOR_TYPE_GRAY )
- fileheader.channel = 1;
- else
- fileheader.channel = 3;
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- fclose(pFile);
- }
- #endif
- #ifdef NICE_USELIB_JPG
- void ImageFile::getJPGHeader()
- {
- struct jpeg_decompress_struct cinfo;
- struct jpeg_error_mgr jerr;
- FILE* pFile;
- if ((pFile = fopen(filename.c_str(), "rb")) == NULL)
- fthrow(ImageException,"ImageFile::readerJPG: Cannot open " + filename);
- cinfo.err = jpeg_std_error(&jerr);
- jpeg_create_decompress(&cinfo);
- jpeg_stdio_src(&cinfo, pFile);
- jpeg_read_header(&cinfo, FALSE);
-
-
-
- jpeg_start_decompress(&cinfo);
- fileheader.width = cinfo.output_width;
- fileheader.height = cinfo.output_height;
- fileheader.channel = cinfo.out_color_components;
- fileheader.bitdepth = cinfo.num_components;
-
- fclose(pFile);
- }
- #endif
- }
|