/**************************************************************************** * MeshLab o o * * An extendible mesh processor o o * * _ O _ * * Copyright(C) 2005, 2009 \/)\/ * * Visual Computing Lab /\/| * * ISTI - Italian National Research Council | * * \ * * All rights reserved. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * * for more details. * * * ****************************************************************************/ #include #include #include #include #include "scalar_image.h" using namespace std; /* Images with bit-depths greater than 8bpp and up to 31bpp are supported by the JJ2000 codec if they are stored in PGX files (one file per component). PGX is a custom monochrome file format invented specifically to simplify the use of JPEG 2000 with images of different bit-depths in the range of 1 to 31 bits per pixel. The file consists of a one line text header followed by the (raw) data. Header: "PG"+ ws ++ ws +[sign]+ws + +" "++" "++[compressed_size]'\n' where: * ws (white-spaces) is any combination of characters ' ' and '\t'. * endianess equals "LM" or "ML"(resp. little-endian or big-endian) * sign equals "+" or "-" (resp. unsigned or signed). If omited, values are supposed to be unsigned. * bit-depth that can be any number between 1 and 31. This number must take into account the eventual sign bit. * width and height are the image dimensions (in pixels). Data: The image binary values appear one after the other (in raster order) immediately after the last header character ('\n') and are byte-aligned (they are packed into 1,2 or 4 bytes per sample, depending upon the bit-depth value). */ template <> bool ScalarImage::Open(const char *filename) { FILE *fp=fopen(filename,"rb"); if(!fp) return false; char buf[256]; fgets(buf,255,fp); qDebug("Header of %s is '%s'",filename,buf); float ll,lh; int depth; char mode; int compressed_size=0; sscanf(buf,"PG LM %i %i %i %c %f %f %i",&depth,&w,&h,&mode,&ll,&lh,&compressed_size); qDebug("image should be of %i x %i %i depth and with range in %f -- %f in mode %c",w,h,depth,ll,lh,mode); if(depth!=16) { qDebug("Wrong depth of image 16 bit expected"); return false; } if (mode != 'l' && mode != 'L') { qDebug("Wrong mode, expected l or L"); return false; } if (mode == 'l') { vector bb(w*h); fread(&*bb.begin(),w*h,sizeof(short),fp); v.resize(w*h); for(int i =0; i bool ScalarImage::Open(const char *filename) { FILE *fp=fopen(filename,"rb"); if(!fp) return false; char buf[256]; fgets(buf,255,fp); qDebug("Header of %s is '%s'",filename,buf); int depth; char mode = ' '; int compressed_size=0; int nrscan = sscanf(buf,"PG LM %i %i %i %c %i",&depth,&w,&h,&mode,&compressed_size); if (nrscan == 3) qDebug("image should be of %i x %i %i depth ",w,h,depth); else qDebug("compressed image of %i x %i %i depth ",w,h,depth); if(depth!=8) { qDebug("Wrong depth of image: 8 bit expected"); return false; } if (mode != 'C') { v.resize(w*h); fread(&*v.begin(),w*h,sizeof(unsigned char),fp); } else { char* compressed_buffer = new char[compressed_size]; fread(compressed_buffer,compressed_size,1,fp); // decompress! unsigned int mysize = w*h; v.resize(w*h); BZ2_bzBuffToBuffDecompress((char*)&*v.begin(), &mysize, compressed_buffer, compressed_size, 0, 0); if (mysize != (unsigned int)(w*h)) { qDebug("This is very wrong. The uncompressed size is not the expected size"); return false; } } fclose(fp); return true; } template <> ScalarImage::ScalarImage(QImage img) { resize(img.width(),img.height()); for(int y=0;y bool ScalarImage::Subsample(const int factor, ScalarImage &fli) { resize(fli.w/factor,fli.h/factor); for(int i=0;i