1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
#include <config.h>
#include <stdio.h>
#include <math.h>
#include <errno.h>
#include "GFile_TIFF.h"
/* GFile (ie. GImage) decendent for reading TIFF files.
*
* Written by: Chris Studholme
* Last Update: 28-May-2000
* Copyright: GPL (http://www.fsf.org/copyleft/gpl.html)
*/
//#define _CHECKS
#ifdef _CHECKS
double VerifyImage(GImageComponent* image, const unsigned char* imagedata,
int w, int h) {
double error=0;
for (int y=0; y<h; ++y)
for (int x=0; x<w; ++x) {
int residule = (imagedata[y*w+x]-128)*128 - image->getPixel(x,y,x+1,y+1);
error += residule*residule;
//error += residule<0 ? -residule : residule;
}
return sqrt(error/w/h)/128;
//return error/w/h/128;
}
#endif
/* ================ GFile_TIFF methods ================ */
GFile_TIFF::GFile_TIFF(const char* filename, bool fast) {
imagefile = TIFFOpen(filename,"r");
if (imagefile==0) {
fprintf(stderr,"GFile_TIFF::GFile_TIFF, cannot read file '%s'\n",filename);
return;
}
ReadImage(fast);
}
/*
GFile_TIFF::GFile_TIFF(FILE* infile) {
imagefile = infile;
ReadImage();
}
*/
GFile_TIFF::~GFile_TIFF() {
if (imagefile)
TIFFClose(imagefile);
if (red)
delete red;
if (green)
delete green;
if (blue)
delete blue;
}
bool GFile_TIFF::supportsFile(FILE* file) {
if (fseek(file,0,SEEK_SET)!=0) {
fprintf(stderr,"GFile_TIFF::supportsFile() fseek() failed %d\n",errno);
return false;
}
unsigned char header[4];
if (fread(header,sizeof(header),1,file)!=1) {
fprintf(stderr,"GFile_TIFF::supportsFile() fread() failed %d\n",errno);
return false;
}
return (((header[0]=='M')&&(header[1]=='M')&&
(header[2]==0)&&(header[3]==42))||
((header[0]=='I')&&(header[1]=='I')&&
(header[2]==42)&&(header[3]==0)));
}
void GFile_TIFF::ReadImage(bool fast) {
TIFFGetField(imagefile, TIFFTAG_IMAGEWIDTH, &w);
TIFFGetField(imagefile, TIFFTAG_IMAGELENGTH, &h);
int npixels = w*h;
uint32* raster = new uint32[npixels];
if (raster==NULL) {
fprintf(stderr,"GFile_TIFF::ReadImage, failed to allocate memory\n");
TIFFClose(imagefile);
imagefile=0;
return;
}
if (!TIFFReadRGBAImage(imagefile, w, h, raster, 0)) {
fprintf(stderr,"GFile_TIFF::ReadImage, failed to read image\n");
TIFFClose(imagefile);
imagefile=0;
return;
}
// process image
unsigned char* color = new unsigned char[npixels];
fprintf(stderr,"Initializing linear matrix... ");
for (int y=0; y<h; ++y)
for (int x=0; x<w; ++x)
color[(h-1-y)*w+x] = TIFFGetR(raster[y*w+x]);
red = new GImageComponent0(color,w,h,fast?-1:0);
#ifdef _CHECKS
fprintf(stderr,"\nRed Error(l1): %g\n",red->getTotalError());
fprintf(stderr,"Red Error(l2): %g\n",VerifyImage(red,color,w,h));
#endif
fprintf(stderr,"red... ");
for (int y=0; y<h; ++y)
for (int x=0; x<w; ++x)
color[(h-1-y)*w+x] = TIFFGetG(raster[y*w+x]);
green = new GImageComponent0(color,w,h,fast?-1:0);
#ifdef _CHECKS
fprintf(stderr,"\nGreen Error(l1): %g\n",green->getTotalError());
fprintf(stderr,"Green Error(l2): %g\n",VerifyImage(green,color,w,h));
#endif
fprintf(stderr,"green... ");
for (int y=0; y<h; ++y)
for (int x=0; x<w; ++x)
color[(h-1-y)*w+x] = TIFFGetB(raster[y*w+x]);
blue = new GImageComponent0(color,w,h,fast?-1:0);
#ifdef _CHECKS
fprintf(stderr,"\nBlue Error(l1): %g\n",blue->getTotalError());
fprintf(stderr,"Blue Error(l2): %g\n",VerifyImage(blue,color,w,h));
#endif
fprintf(stderr,"blue, done.\n");
if (!fast)
fprintf(stderr,"Total Error is %g\n",red->getTotalError()+
green->getTotalError()+blue->getTotalError());
delete[] color;
delete[] raster;
}
const char* GFile_TIFF::getComments() {
return NULL;
}
/* width/height of individual pixel */
double GFile_TIFF::getAspectRatio() {
return 1;
}
|