/********************************************************************** * $Id: pgraster_utils.c 2007-07-22 XingLin $ * * PostGIS - Spatial Types for PostgreSQL * http://postgis.refractions.net * Copyright 2001-2003 Refractions Research Inc. * * This is free software; you can redistribute and/or modify it under * the terms of the GNU General Public Licence. See the COPYING file. * ********************************************************************** * * PGRaster - Raster/Coverage Model for PostgreSQL/PostGIS * ********************************************************************** * * File Name: pgraster_utils.c * * Author: Xing Lin * * Create Date: 2007-07-22 * * Description: This file will include the implementation of utility * functions will be used in the loader/export program. * * Original Author: Xing Lin * * Maintainer: Xing Lin * * Last Update: 2007-07-22 * **********************************************************************/ #include "pgraster_utils.h" #include "pgraster_types.h" #include "pgraster_const.h" #include "math.h" #pragma pack(1) /* Some byte data reading/seeking tools */ void skipbyte(byte **c) { *c+=1; } byte readbyte(byte *c) { byte b=0; memcpy(&b, c, 1); return b; } byte popbyte(byte **c) { return *((*c)++); } void skipchar(byte **c) { *c+=1; } char readchar(byte *c) { return *((char*)c); } char popchar(byte **c) { return *((*c)++); } _uint16 popuint16(byte **c) { _uint16 i=0; memcpy(&i, *c, 2); *c+=2; return i; } _uint16 readuint16(byte *c) { _uint16 i=0; memcpy(&i, c, 2); return i; } void skipuint16(byte **c) { *c+=2; } _int16 popint16(byte **c) { _int16 i=0; memcpy(&i, *c, 2); *c+=2; return i; } _int16 readint16(byte *c) { _int16 i=0; memcpy(&i, c, 2); return i; } void skipint16(byte **c) { *c+=2; } _uint32 popuint32(byte **c) { _uint32 i=0; memcpy(&i, *c, 4); *c+=4; return i; } _uint32 readuint32(byte *c) { _uint32 i=0; memcpy(&i, c, 4); return i; } void skipuint32(byte **c) { *c+=4; } _int32 popint32(byte **c) { _int32 i=0; memcpy(&i, *c, 4); *c+=4; return i; } _int32 readint32(byte *c) { _int32 i=0; memcpy(&i, c, 4); return i; } void skipint32(byte **c) { *c+=4; } float popfloat(byte **c) { float f=0.0; memcpy(&f, *c, 4); *c+=4; return f; } float readfloat(byte *c) { float f=0.0; memcpy(&f, c, 4); return f; } void skipfloat(byte **c) { *c+=4; } double popdouble(byte **c) { double d=0.0; memcpy(&d, *c, 8); *c+=8; return d; } double readdouble(byte *c) { double d=0.0; memcpy(&d, c, 8); return d; } void skipdouble(byte **c) { *c+=8; } /* PGRColorRGB readColorRGB(byte *c); PGRColorRGB popColorRGB(byte **c); void skipColorRGB(byte **c); PGRColorRGBA readColorRGBA(byte *c); PGRColorRGBA popColorRGBA(byte **c); void skipColorRGBA(byte **c); */ /* * Test whether the client is in a big_endian or little_endian environment. * * Support for both big_endian and little_endian will come soon. * */ int is_bigendian(void) { int test = 1; if ( (((char *)(&test))[0]) == 1) { return 0; /*NDR (little_endian) */ } else { return 1; /*XDR (big_endian) */ } } /* * Initialize PGRasterMetadata to Default Values */ void initialize_metadata(PGRasterMetadata *pgrMeta) { // simply return for null pointer if(pgrMeta == NULL) return; pgrMeta->rasterObjectID = -1; pgrMeta->name = NULL; pgrMeta->captureDate = NULL; // DATE Format "YYYY-MM-DD" pgrMeta->rasterDimensions = 0; pgrMeta->rasterBandType = BT_UNKNOWN; pgrMeta->rasterDataType = DT_UNKNOWN; pgrMeta->rasterValueType = VT_NOTHING; pgrMeta->rasterDataTable = "PGRASTER_DATA\0"; pgrMeta->rasterBandCount = 0; pgrMeta->rasterRowCount = 0; pgrMeta->rasterColumnCount = 0; pgrMeta->rasterCellDepth = 0; pgrMeta->rasterPyramidEnabled = TRUE; pgrMeta->rasterPyramidDepth = 0; pgrMeta->blockSizeBands = -1; pgrMeta->blockSizeRows = 256; pgrMeta->blockSizeColumns = 256; pgrMeta->blockPadding = TRUE; pgrMeta->blockBandInterleaving = BI_BSQ; pgrMeta->blockCompression = CT_LZW; pgrMeta->blockQuality = 100; pgrMeta->nodataValue = -1; pgrMeta->SRID = -1; pgrMeta->geoReferenced = FALSE; pgrMeta->spatialExtent = NULL; } /* * Initialize PGRasterData to Default Values */ void initialize_data(PGRasterData *pgrData) { // simply return for null pointer if(pgrData == NULL) return; pgrData->rasterObjectID = -1; pgrData->pyramidLevel = -1; pgrData->bandBlockNumber = -1; pgrData->rowBlockNumber = -1; pgrData->columnBlockNumber = -1; pgrData->blockBandSize = 256; pgrData->blockRowSize = 256; pgrData->blockColumnSize = 256; pgrData->blockMBR = NULL; pgrData->dataBlock = NULL; pgrData->nDataLength = 0; } /* LowerCase */ void LowerCase(char *s) { int j; for (j=0; jnBlockVertical)?nBlockHorizontal:nBlockVertical; nLowerWidth = (rows>cols)?cols:rows; nBlocks = nBiggerBlock; for(l = 0 ; ;l++) { if(pow(2,l) >= nBlocks) break; else continue; } for(n = 0;;n++) { if(pow(2,n) >= nLowerWidth) break; else continue; } nPyramidDepth = ((n > l)?l:n)+1; return nPyramidDepth; } } byte SetSingleBitAt(byte in, byte bit, byte pos) { if(bit == 0) in = ~in; if(pos == 0) in = (in | 128); else if (pos == 1) in = (in | 64 ); else if (pos == 2) in = (in | 32 ); else if (pos == 3) in = (in | 16 ); else if (pos == 4) in = (in | 8 ); else if (pos == 5) in = (in | 4 ); else if (pos == 6) in = (in | 2 ); else // if (pos == 7) in = (in | 2); if(bit == 0) in = ~in; return in; } // To Be Finish. byte GetSingleBitAt(byte in, byte pos) { if(pos >= 8) return 0; else { return (in<>7; } } byte SetMultiBitAt(byte in, byte bits, byte count, byte pos) { return in; /* if(count == 1) { return SetSingleBitAt(in, bits, pos); } else if(count == 2 && pos <= 6) { bits = bits << (6-pos); } else if(count == 3 && pos <= 5) { } else if(count == 4 && pos <= 4) { } else if(count == 5 && pos <= 3) { } else if(count == 6 && pos <= 2) { } else if(count == 7 && pos <= 1) { } else if(count == 8) return bits; else return in; */ } byte GetMultiBitAt(byte in, byte pos, byte count) { if( pos > 7 ) return 0; else if ((pos+count) > 8) return 0; else { return (in<>(8-count); } } /* ntoh, ntol and so on*/ _uint16 _htons(_uint16 n) { return ((n & 0xFF) << 8) | ((n & 0xFF00) >> 8); } _uint16 _ntohs(_uint16 n) { return ((n & 0xFF) << 8) | ((n & 0xFF00) >> 8); } _uint32 _htonl(_uint32 n) { return ((n & 0xFF) << 24) | ((n & 0xFF00) << 8) | ((n & 0xFF0000) >> 8) | ((n & 0xFF000000) >> 24); } _uint32 _ntohl(_uint32 n) { return ((n & 0xFF) << 24) | ((n & 0xFF00) << 8) | ((n & 0xFF0000) >> 8) | ((n & 0xFF000000) >> 24); } _uint64 _htonll(_uint64 n) { //return ((n & 0xFF) << 56) | ((n & 0xFF00) << 8) | ((n & 0xFF0000) >> 8) | ((n & 0xFF000000) >> 24); return ((_uint64)(_ntohl((_uint32)((n << 32) >> 32))) << 32) | (_uint32)_ntohl(((int)(n >> 32))); } _uint64 _ntohll(_uint64 n) { return _htonll(n); } double _htond(double f) { union { double f; _uint32 h[2]; }swap; swap.f = f; swap.h[0] = _ntohl(swap.h[0]); swap.h[1] = _ntohl(swap.h[1]); if (!is_bigendian()) // little endian { _uint32 temp = swap.h[0]; swap.h[0] = swap.h[1]; swap.h[1] = temp; } return swap.f; } double _ntohd(double f) { union { double f; _uint32 h[2]; }swap; swap.f = f; swap.h[0] = _ntohl(swap.h[0]); swap.h[1] = _ntohl(swap.h[1]); if (!is_bigendian()) // little endian { _uint32 temp = swap.h[0]; swap.h[0] = swap.h[1]; swap.h[1] = temp; } return swap.f; } float _htonf(float f) { union { float f; _uint32 i; }swap; swap.f = f; swap.i = _htonl(swap.i); return swap.f; } float _ntohf(float f) { union { float f; _uint32 i; }swap; swap.f = f; swap.i = _ntohl(swap.i); return swap.f; } #pragma pack()