dibtiff.cpp
上传用户:lbr_007
上传日期:2019-05-31
资源大小:282k
文件大小:18k
- // dibtif.cpp
- //
- #include "stdafx.h"
- #include "dibtiff.h"
- #include <math.h>
- #include "tiffio.h"
- #include "geotiffio.h"
- #include "geo_normalize.h"
- #include "geo_tiffp.h"
- //#include "geoproj.h"
- #include <string>
- #include <UtilProcess.h>
- #include <UtilityParser.h>
- #include <StringUtil.h>
- using namespace std;
- extern char * GetInitialFolder(void);
- #define ROUND(x) (u_short) ((x) + 0.5)
- #define TIFF_GAMMA 2.2
- void ConvertToPDF(const char * tiffName, const char * pdfName)
- {
- const char * args[4];
- args[0] = "tiff2pdf";
- args[1] = "-o";
- args[2] = pdfName;
- args[3] = tiffName;
- string cmd = "tiff2pdf -o ";
- cmd += pdfName;
- cmd += " ";
- cmd += tiffName;
- //system(cmd.c_str());
- UtilProcess p;
- p.CreateProcess("tiff2pdf.exe", cmd.c_str(), false);
- }
- int ReadTIFFDirectories(const char * filename, ArrayContainer<TIFFSubImage>& images)
- {
- int result = 0;
- TIFF * tiff = TIFFOpen((char *)filename,"r");
- if (tiff)
- {
- int m_num_items = TIFFNumberOfDirectories(tiff);
- if (m_num_items > 0)
- {
- for (int i=0;i<m_num_items;i++){
- tdir_t d = (tdir_t)i;
- TIFFSetDirectory(tiff,d);
- int w=0, h=0;
- int bpp = 0;
- char name[256];
- memset(name,0,(size_t)256);
- sprintf(name,"image%d",i);
- // 2)
- // Get the width and height of the image
- TIFFGetField(tiff,TIFFTAG_IMAGEWIDTH, &w);
- TIFFGetField(tiff,TIFFTAG_IMAGELENGTH, &h);
- TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bpp);
- TIFFSubImage ti(w,h,i,bpp,name);
- if (ti.IsCreated())
- {
- images.AddElement(ti);
- result++;
- }
- }
- }
- TIFFClose(tiff);
- }
- return result;
- }
- void RGBA_to_BGRA(BYTE* data,int width,int height)
- {
- int i;
- int j;
- int line_width;
- BYTE r, g, b, a;
- BYTE* ptr;
- ptr = data;
- line_width = width * 4;
- for(i = 0; i < height; i++)
- {
- ptr = data + line_width*i;
- for(j = 0; j < width; j++)
- {
- r = ptr[0];
- g = ptr[1];
- b = ptr[2];
- a = ptr[3];
- ptr[2] = (BYTE)( (r*a+1) >> 8 );
- ptr[1] = (BYTE)( (g*a+1) >> 8 );
- ptr[0] = (BYTE)( (b*a+1) >> 8 );
- ptr += 4;
- }
- }
- return;
- }
- void BGRA_to_RGBA(BYTE* data,int width,int height, int pad)
- {
- int i;
- int j;
- int line_width;
- BYTE r, g, b, a;
- BYTE* ptr;
- ptr = data;
- line_width = width * 4;
- for(i = 0; i < height; i++)
- {
- ptr = data + line_width*i;
- for(j = 0; j < width; j++)
- {
- b = ptr[0];
- g = ptr[1];
- r = ptr[2];
- a = ptr[3];
- ptr[0] = r;
- ptr[1] = g;
- ptr[2] = b;
- ptr += 4;
- }
- }
- return;
- }
- int OpenTIFF2DIB(const char * filename, DIBSection& dib, int directory)
- {
- int result = 0;
- TIFF * tiff = TIFFOpen((char *)filename,"r");
- if (tiff)
- {
- int w=0, h=0;
- tdir_t d = (tdir_t)directory;
- TIFFSetDirectory(tiff,d);
- TIFFGetField(tiff,TIFFTAG_IMAGEWIDTH, &w);
- TIFFGetField(tiff,TIFFTAG_IMAGELENGTH, &h);
- if ((w > 0) && (h > 0))
- {
- UINT32 * raster = new UINT32[(w*h)];
- if (raster)
- {
- dib.Create(w,h,24);
- UINT32 tw = dib.GetTotalWidth();
- if (TIFFReadRGBAImage(tiff, w, h, (unsigned long *)raster, 0))
- {
- RGBA_to_BGRA((BYTE *)raster,w,h);
- unsigned char * dest = (unsigned char *)dib.GetBits();
- unsigned char * src = (unsigned char *)raster;
- unsigned char * ptr_dest;
- unsigned char * ptr_src;
- int row, col;
- for (row=0; row < h; row++){
- ptr_dest = dest + row * tw * 3;
- ptr_src = src + row * w * 4;
- for (col=0; col < w; col++){
- memcpy(ptr_dest,ptr_src,3);
- ptr_dest += 3;
- ptr_src += 4;
- }
- }
- result++;
- }
- delete [] raster;
- }
- }
- TIFFClose(tiff);
- GEORef gr;
- if (ReadGeoInfo(filename,gr))
- {
- gr.m_rows = h;
- gr.m_cols = w;
- dib.SetGeoReference(gr);
- }
- }
- return result;
- }
- bool ReadGeoInfo(const char * filename, GEORef& gr)
- {
- bool result = false;
- TIFF * tiff = 0;
- GTIF * gtif = 0;
- tiff = XTIFFOpen(filename,"r");
- if (tiff)
- {
- gtif = GTIFNew(tiff);
- if (gtif)
- {
- const int key_size = 2048;
- char key_data[key_size];
- memset(key_data,0,(size_t)key_size);
- tagtype_t cit_type;
- int cit_size;
- INT32 ellps = 1;
- string geoCitationKey;
- double * d_list = 0;
- int d_list_count = 0;
- int cit_len = GTIFKeyInfo(gtif,GTCitationGeoKey, &cit_size, &cit_type);
- if (cit_len)
- {
- if (GTIFKeyGet(gtif,GTCitationGeoKey,key_data,0,cit_len))
- {
- geoCitationKey = (char *)key_data;
- }
- }
- if (geoCitationKey.length() == 0)
- {
- char * gt_ascii = 0;
- if (TIFFGetField(tiff, GTIFF_ASCIIPARAMS, >_ascii))
- {
- geoCitationKey = (char *)gt_ascii;
- }
- }
- if (geoCitationKey.length() > 0)
- {
- UtilityParser p;
- p.ParseString(geoCitationKey);
- if (p.GetSize() > 0)
- {
- vector<string> * pArgs = p.GetData();
- UINT32 argSize = pArgs->size();
- bool utmproj = false;
- for (UINT32 i = 0; i < argSize; i++){
- string iArg = (*pArgs)[i];
- StringUtil::Uppercase(iArg);
- if (iArg == "UTM")
- {
- utmproj = true;
- }
- if (utmproj && StringUtil::IsIntNumber(iArg))
- {
- gr.m_proj = GEORef::UTM;
- gr.m_zone = atoi(iArg.c_str());
- gr.m_ellipse = GEORef::Clarke1866;
- result = true;
- }
- if ((iArg == "ZONE") && (i < (argSize-1)) && (utmproj))
- {
- iArg = (*pArgs)[i+1];
- char cZone[3];
- cZone[0] = iArg.c_str()[0];
- cZone[1] = iArg.c_str()[1];
- cZone[2] = 0;
- int zone = atoi(cZone);
- gr.m_proj = GEORef::UTM;
- gr.m_zone = zone;
- result = true;
- }
- if (StringUtil::StartsWith(iArg,"WGS84"))
- {
- //
- // USGS digital raster graphics say WGS84, but
- // they appear to actually be NAD27 using Clarke's
- // ellipsoid of 1866. Use GEORef::WGS84 if you
- // are sure that your map is WGS84
- //
- gr.m_ellipse = GEORef::Clarke1866;//GEORef::WGS84;
- }
- if (StringUtil::StartsWith(iArg,"NAD27"))
- {
- gr.m_ellipse = GEORef::Clarke1866;
- }
- }
- }
- }
- if (TIFFGetField(tiff, GTIFF_TIEPOINTS, &d_list_count, &d_list))
- {
- gr.m_tieX = d_list[3];
- gr.m_tieY = d_list[4];
- }
- if (TIFFGetField(tiff, GTIFF_PIXELSCALE, &d_list_count, &d_list))
- {
- gr.m_resX = d_list[0];
- gr.m_resY = d_list[1];
- }
- XTIFFClose(tiff);
- GTIFFree(gtif);
- }
- }
- return result;
- }
- void GetTIFFProperties(const char * tiffName, UINT32 subImage,
- ArrayContainer<std::string>& properties)
- {
- TIFF * tiff = TIFFOpen((char *)tiffName,"r");
- if (tiff)
- {
- int w=0, h=0, bps=0, packbits=0, photo=0, spp=0, rps=0;
- int orient=0;
- tdir_t d = (tdir_t)subImage;
- TIFFSetDirectory( tiff, d );
- TIFFGetField(tiff,TIFFTAG_IMAGEWIDTH, &w);
- TIFFGetField(tiff,TIFFTAG_IMAGELENGTH, &h);
- TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bps);
- TIFFGetField(tiff, TIFFTAG_COMPRESSION, &packbits);
- TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photo);
- TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &spp);
- TIFFGetField(tiff, TIFFTAG_ROWSPERSTRIP, &rps);
- TIFFGetField(tiff, TIFFTAG_ORIENTATION, &orient);
- string s;
- char txt[256];
- memset(txt, 0, (size_t)256);
- sprintf(txt,"TIFFTAG_IMAGEWIDTH = %d",w);
- s = txt;
- properties.AddElement(s);
- memset(txt, 0, (size_t)256);
- sprintf(txt,"TIFFTAG_IMAGELENGTH = %d",h);
- s = txt;
- properties.AddElement(s);
- memset(txt, 0, (size_t)256);
- sprintf(txt,"TIFFTAG_BITSPERSAMPLE = %d",bps);
- s = txt;
- properties.AddElement(s);
- memset(txt, 0, (size_t)256);
- sprintf(txt,"TIFFTAG_COMPRESSION = ");
- s = txt;
- switch (packbits){
- case COMPRESSION_NONE: s += "NONE"; break;
- case COMPRESSION_CCITTRLE: s += "CCITTRLE"; break;
- case COMPRESSION_CCITTFAX3: s += "CCITTFAX3 or CCITT_T4"; break;
- case COMPRESSION_CCITTFAX4: s += "CCITTFAX4 or CCITT_T6"; break;
- case COMPRESSION_LZW: s += "LZW"; break;
- case COMPRESSION_OJPEG: s += "OJPEG"; break;
- case COMPRESSION_JPEG: s += "JPEG"; break;
- case COMPRESSION_NEXT: s += "NEXT"; break;
- case COMPRESSION_CCITTRLEW: s += "CCITTRLEW"; break;
- case COMPRESSION_PACKBITS: s += "PACKBITS"; break;
- case COMPRESSION_THUNDERSCAN: s += "THUNDERSCAN"; break;
- /* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT <dkelly@apago.com) */
- case COMPRESSION_IT8CTPAD: s += "IT8CTPAD"; break;
- case COMPRESSION_IT8LW: s += "IT8LW"; break;
- case COMPRESSION_IT8MP: s += "IT8MP"; break;
- case COMPRESSION_IT8BL: s += "IT8BL"; break;
- /* compression codes 32908-32911 are reserved for Pixar */
- case COMPRESSION_PIXARFILM: s += "PIXARFILM"; break;
- case COMPRESSION_PIXARLOG: s += "PIXARLOG"; break;
- case COMPRESSION_DEFLATE: s += "DEFLATE"; break;
- case COMPRESSION_ADOBE_DEFLATE: s += "ADOBE_DEFLATE"; break;
- /* compression code 32947 is reserved for Oceana Matrix <dev@oceana.com> */
- case COMPRESSION_DCS: s += "DCS"; break;
- case COMPRESSION_JBIG: s += "JBIG"; break;
- case COMPRESSION_SGILOG: s += "SGILOG"; break;
- case COMPRESSION_SGILOG24: s += "SGILOG24"; break;
- //case COMPRESSION_JP2000: s += "JP2000"; break;
- }
- properties.AddElement(s);
- memset(txt, 0, (size_t)256);
- sprintf(txt,"TIFFTAG_PHOTOMETRIC = ");
- s = txt;
- switch (photo){
- case PHOTOMETRIC_MINISWHITE: s += "MINISWHITE"; break;
- case PHOTOMETRIC_MINISBLACK: s += "MINISBLACK"; break;
- case PHOTOMETRIC_RGB: s += "RGB"; break;
- case PHOTOMETRIC_PALETTE: s += "PALETTE"; break;
- case PHOTOMETRIC_MASK: s += "MASK"; break;
- case PHOTOMETRIC_SEPARATED: s += "SEPARATED"; break;
- case PHOTOMETRIC_YCBCR: s += "YCBCR"; break;
- case PHOTOMETRIC_CIELAB: s += "CIELAB"; break;
- //case PHOTOMETRIC_ICCLAB: s += "ICCLAB"; break;
- case PHOTOMETRIC_ITULAB: s += "ITULAB"; break;
- case PHOTOMETRIC_LOGL: s += "LOGL"; break;
- case PHOTOMETRIC_LOGLUV: s += "LOGLUV"; break;
- }
- properties.AddElement(s);
- memset(txt, 0, (size_t)256);
- sprintf(txt,"TIFFTAG_SAMPLESPERPIXEL = %d",spp);
- s = txt;
- properties.AddElement(s);
- TIFFClose(tiff);
- GEORef gr;
- if (ReadGeoInfo(tiffName,gr))
- {
- memset(txt, 0, (size_t)256);
- sprintf(txt,"GTIFF_TIEPOINTS = ( %.2f, %.2f )",gr.m_tieX,gr.m_tieY);
- s = txt;
- properties.AddElement(s);
- memset(txt, 0, (size_t)256);
- sprintf(txt,"GTIFF_PIXELSCALE = ( %.7f, %.7f )",gr.m_resX,gr.m_resY);
- s = txt;
- properties.AddElement(s);
- memset(txt, 0, (size_t)256);
- sprintf(txt,"UTM Zone = %d",gr.m_zone);
- s = txt;
- properties.AddElement(s);
- }
- }
- }
- int SaveDIB2TIFF(const char * output_file, DIBSection& dib)
- {
- int result = 0;
- UINT32 w = dib.Width();
- UINT32 h = dib.Height();
- UINT32 total_width = dib.GetTotalWidth();
- UINT32 bitcount = dib.GetBitCount();
- UINT32 bytecount = bitcount / 8;
- if (dib.IsCreated() && (w > 0) && (h > 0))
- {
- double image_gamma = TIFF_GAMMA;
- TIFF * tif;
- if ((tif = TIFFOpen(output_file, "w")) == NULL)
- {
- return result;
- }
- // setup the image tags
- TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, w);
- TIFFSetField(tif, TIFFTAG_IMAGELENGTH, h);
- TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
- TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_PACKBITS);
- TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
- TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
- TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
- TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
- TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE);
- TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
- unsigned char * psrc = (unsigned char *)dib.GetBits();
- unsigned char * pdst = new unsigned char[(w * 3)];
- UINT32 src_index;
- UINT32 dst_index;
- // now go line by line to write out the image data
- for (int row = 0; row < h; row++ ){
- // initialize the scan line to zero
- memset(pdst,0,(size_t)(w * 3));
- // moving the data from the dib to a row structure that can
- // be used by the tiff library
- for (int col = 0; col < w; col++){
- src_index = (h - row - 1) * total_width * bytecount + col * bytecount;
- dst_index = col * 3;
- pdst[dst_index++] = psrc[src_index+2];
- pdst[dst_index++] = psrc[src_index+1];
- pdst[dst_index] = psrc[src_index];
- result++;
- }
- // now actually write the row data
- TIFFWriteScanline(tif, pdst, row, 0);
- }
- TIFFClose(tif);
- }
- return result;
- }
- int OpenBigTIFF2DIB(const char * lpFileName, DIBSection& dib, int directory)
- {
- int result = 0;
- TIFF *tif;
- unsigned long imageLength;
- unsigned long imageWidth;
- unsigned int BitsPerSample;
- unsigned long LineSize;
- unsigned int SamplePerPixel;
- unsigned long RowsPerStrip;
- int PhotometricInterpretation;
- long nrow;
- unsigned long row;
- char *buf;
- char *lpBits;
- HGLOBAL hStrip;
- int i,l;
- int Align;
- bool bigTiff = false;
-
- tif = TIFFOpen(lpFileName, "r");
-
- if (!tif)
- {
- return result;
- }
- tdir_t d = (tdir_t)directory;
- TIFFSetDirectory(tif,d);
-
- TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imageWidth);
- TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageLength);
- TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &BitsPerSample);
- TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip);
- TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip);
- TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &PhotometricInterpretation);
-
- LineSize = TIFFScanlineSize(tif); //Number of byte in ine line
- SamplePerPixel = (int) (LineSize/imageWidth);
- //Align = Number of byte to add at the end of each line of the DIB
- Align = 4 - (LineSize % 4);
- if (Align == 4) Align = 0;
-
- //Create a new DIB
- double dw = imageWidth;
- double dh = imageLength;
- double img_scale = 1.0;
- double hscale, vscale;
- const double MaxImageDimension = 4096;
- if ((imageWidth > MaxImageDimension) || (imageLength > MaxImageDimension))
- {
- bigTiff = true;
- if (dw > dh)
- {
- img_scale = (dw/MaxImageDimension);
- dh /= img_scale;
- dw = MaxImageDimension;
- hscale = (double)imageWidth/dw;
- vscale = (double)imageLength/dh;
- }
- else if (dw < dh)
- {
- img_scale = (dh/MaxImageDimension);
- dw /= img_scale;
- dh = MaxImageDimension;
- hscale = (double)imageWidth/dw;
- vscale = (double)imageLength/dh;
- }
- else
- {
- img_scale = (dh/MaxImageDimension);
- dw = MaxImageDimension;
- dh = MaxImageDimension;
- hscale = (double)imageWidth/dw;
- vscale = (double)imageLength/dh;
- }
- INT32 w = (INT32)(dw + 0.50);
- INT32 h = (INT32)(dh + 0.50);
- dib.Create(w,h,24);
-
- lpBits = (char *)dib.GetBits();
- //In the tiff file the lines are save from up to down
- //In a DIB the lines must be save from down to up
- if (lpBits)
- {
- hStrip = GlobalAlloc(GHND,TIFFStripSize(tif));
- buf = (char *)GlobalLock(hStrip);
- if (!buf)
- goto OutOfBufMemory;
- //read the tiff lines and save them in the DIB
- //with RGB mode, we have to change the order of the 3 samples RGB
- // <=> BGR
- UINT32 next_row = 0;
- UINT32 current_row = 0;
- UINT32 img_row = 0;
- UINT32 src_col, src_row, dst_ndx, total_width;
- UINT32 row_incr = (UINT32)(vscale + 0.50);
- total_width = dib.GetTotalWidth();
- for (row = 0; row < imageLength; row += row_incr){
- nrow = (row + RowsPerStrip > imageLength ? imageLength - row :
- RowsPerStrip);
- if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
- buf, nrow*LineSize)==-1)
- {
- goto TiffReadError;
- }
- else
- {
- for (l = 0; l < nrow; l++){
- if (SamplePerPixel == 3)
- {
- for (i=0;i<w;i++){
- src_col = (UINT32)(hscale * i + 0.50);
- if (src_col > imageWidth) src_col = imageWidth;
- src_row = l*LineSize;
- dst_ndx = 3 * (i + (h - img_row - 1) * total_width);
- lpBits[dst_ndx] = buf[src_row+src_col*SamplePerPixel+2];
- lpBits[++dst_ndx] = buf[src_row+src_col*SamplePerPixel+1];
- lpBits[++dst_ndx] = buf[src_row+src_col*SamplePerPixel+0];
- }
- img_row++;
- if (img_row == h) break;
- }
- }
- if (img_row == h) break;
- }
- }
- result++;
- GlobalUnlock(hStrip);
- GlobalFree(hStrip);
- }
- TIFFClose(tif);
- }
- else
- {
- /*
- INT32 w = imageWidth;
- INT32 h = imageLength;
- dib.Create(w,h,24);
-
- lpBits = (char *)dib.GetBits();
- if (lpBits)
- {
- hStrip = GlobalAlloc(GHND,TIFFStripSize(tif));
- buf = (char *)GlobalLock(hStrip);
- if (!buf)
- goto OutOfBufMemory;
- //read the tiff lines and save them in the DIB
- //with RGB mode, we have to change the order of the 3 samples RGB
- // <=> BGR
- UINT32 next_row = 0;
- UINT32 current_row = 0;
- UINT32 img_row = 0;
- UINT32 src_col, src_row, dst_ndx, total_width;
- UINT32 row_incr = 1;
- total_width = dib.GetTotalWidth();
- for (row = 0; row < imageLength; row++){
- nrow = ((row + RowsPerStrip) > imageLength) ? (imageLength - row) :
- (RowsPerStrip);
- if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
- buf, nrow*LineSize) == -1)
- {
- goto TiffReadError;
- }
- else
- {
- if (SamplePerPixel == 3)
- {
- for (l = 0; l < nrow; l++){
- for (i=0;i<w;i++){
- src_col = i;
- if (src_col > imageWidth) src_col = imageWidth;
- src_row = l*LineSize;
- dst_ndx = 3 * (i + (h - img_row - 1) * total_width);
- lpBits[dst_ndx] = buf[src_row+src_col*SamplePerPixel+2];
- lpBits[++dst_ndx] = buf[src_row+src_col*SamplePerPixel+1];
- lpBits[++dst_ndx] = buf[src_row+src_col*SamplePerPixel+0];
- }
- img_row++;
- if (img_row == h) break;
- }
- }
- if (img_row == h) break;
- }
- }
- }
- result++;
- GlobalUnlock(hStrip);
- GlobalFree(hStrip);
- */
- TIFFClose(tif);
- return OpenTIFF2DIB(lpFileName,dib,directory);
- }
- return result;
- OutOfBufMemory:
- TiffReadError:
- GlobalFree(hStrip);
- }