00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <cstdio>
00020 #ifndef USING_MINGW
00021 #include <sys/mman.h>
00022 #else
00023 #define MAP_FAILED -1
00024 #endif
00025
00026 #include <tiffio.h>
00027 #include <qimage.h>
00028 #include <qfile.h>
00029
00030
00032
00033 static tsize_t tiff_read(thandle_t handle,tdata_t data,tsize_t size) {
00034 QIODevice *iod=(QIODevice*) handle;
00035 return (tsize_t) iod->readBlock((char*) data,size);
00036 }
00037
00039
00040 static tsize_t tiff_write(thandle_t handle,tdata_t data,tsize_t size) {
00041 QIODevice *iod=(QIODevice*) handle;
00042 return (tsize_t) iod->writeBlock((const char*) data,size);
00043 }
00044
00045
00047
00049 static toff_t tiff_seek(thandle_t handle, toff_t offset, int whence) {
00050 QIODevice *iod=(QIODevice*) handle;
00051 if(whence==SEEK_SET)
00052 iod->at(offset);
00053 else if(whence==SEEK_CUR)
00054 iod->at(iod->at()+offset);
00055 else if(whence==SEEK_END)
00056 iod->at(iod->size()+offset);
00057 else
00058 return ( toff_t )-1;
00059
00060 return iod->at();
00061 }
00062
00064
00066 static int tiff_close(thandle_t) {
00067 return 0;
00068 }
00069
00071
00072 static toff_t tiff_size(thandle_t handle) {
00073 QIODevice *iod=(QIODevice*) handle;
00074 return iod->size();
00075 }
00076
00078
00080 static int tiff_mmap(thandle_t, tdata_t* ,toff_t* ) {
00081 return (long) MAP_FAILED;
00082 }
00083
00085
00087 static void tiff_unmap(thandle_t , tdata_t , toff_t ) {
00088 }
00089
00091
00092 static void read_tiff_image(QImageIO *iio) {
00093 QImage img;
00094 int state=-1;
00095
00096
00097
00098 const char *fileName;
00099 QFile *f=dynamic_cast<QFile*>(iio->ioDevice());
00100 fileName=f ? f->name() : QString("QIODevice");
00101
00102
00103
00104 TIFF *tif=TIFFClientOpen(fileName,"rm",
00105 (thandle_t) (iio->ioDevice()),
00106 tiff_read,
00107 tiff_write,
00108 tiff_seek,
00109 tiff_close,
00110 tiff_size,
00111 tiff_mmap,
00112 tiff_unmap );
00113
00114 if(tif) {
00115 unsigned width, height,size;
00116
00117 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
00118 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
00119 size=width*height;
00120 uint32 *bits=(uint32*) _TIFFmalloc(size * sizeof (uint32));
00121
00122 if(bits) {
00123 if (TIFFReadRGBAImage(tif, width, height, bits, 0)) {
00124
00125
00126 img.create(width,height,32);
00127
00128
00129
00130
00131 if(TIFFGetR(0x1234567)==qRed (0x1234567) &&
00132 TIFFGetG(0x1234567)==qGreen(0x1234567) &&
00133 TIFFGetB(0x1234567)==qBlue (0x1234567) ) {
00134
00135
00136
00137 for(unsigned y=0; y<height; y++)
00138 memcpy(img.scanLine(height-1-y),bits+y*width,width*4);
00139
00140 } else {
00141
00142
00143
00144 uint32 *inp=bits;
00145 for(unsigned y=0; y<height; y++) {
00146 QRgb *row=(QRgb*) (img.scanLine(height-1-y));
00147 for(unsigned x=0; x<width; x++) {
00148 const uint32 col=*(inp++);
00149 row[x]=qRgb(TIFFGetR(col),
00150 TIFFGetG(col),
00151 TIFFGetB(col) ) |
00152 (TIFFGetA(col)<<24);
00153 }
00154 }
00155
00156 }
00157 iio->setImage(img);
00158 state=0;
00159
00160 }
00161 _TIFFfree(bits);
00162 }
00163 TIFFClose(tif);
00164 }
00165 iio->setStatus(state);
00166 }
00167
00169
00170 static void write_tiff_image(QImageIO *iio) {
00171 int state=-1;
00172
00173
00174
00175 iio->setStatus(state);
00176 }
00177
00179
00180 void qInitTiffIO() {
00181
00182
00183 QImageIO::defineIOHandler("TIFF", "^[MI][MI][\\x01*][\\x01*]", 0,
00184 read_tiff_image,
00185 write_tiff_image);
00186 }