root/tags/gdal_1_3_2/gcore/rasterio.cpp

Revision 9398, 58.9 kB (checked in by fwarmerdam, 3 years ago)

updated contact info

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /******************************************************************************
2  * $Id$
3  *
4  * Project:  GDAL Core
5  * Purpose:  Contains default implementation of GDALRasterBand::IRasterIO()
6  *           and supporting functions of broader utility.
7  * Author:   Frank Warmerdam, warmerdam@pobox.com
8  *
9  ******************************************************************************
10  * Copyright (c) 1998, Frank Warmerdam
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included
20  * in all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28  * DEALINGS IN THE SOFTWARE.
29  ******************************************************************************
30  *
31  * $Log$
32  * Revision 1.33  2006/03/28 14:49:56  fwarmerdam
33  * updated contact info
34  *
35  * Revision 1.32  2005/06/26 00:16:51  fwarmerdam
36  * Performance improvements to GDALCopyWords() from Steve Sproule (Vexcel).
37  *
38  * Revision 1.31  2005/05/23 06:43:10  fwarmerdam
39  * Updated for locking of block refs
40  *
41  * Revision 1.30  2005/04/04 15:24:48  fwarmerdam
42  * Most C entry points now CPL_STDCALL
43  *
44  * Revision 1.29  2005/02/17 22:12:39  fwarmerdam
45  * ensure that GDALDataset::BlockRasterIO() calls blocking band RasterIO
46  *
47  * Revision 1.28  2003/05/21 04:40:13  warmerda
48  * avoid warnings
49  *
50  * Revision 1.27  2003/05/07 19:11:48  warmerda
51  * fixed bug in one case of bJustInitialize setting
52  *
53  * Revision 1.26  2003/04/30 17:13:48  warmerda
54  * added docs for many C functions
55  *
56  * Revision 1.25  2003/04/28 20:47:09  warmerda
57  * block oriented dataset io now working well
58  *
59  * Revision 1.24  2003/04/25 19:57:14  warmerda
60  * Avoid warning.
61  *
62  * Revision 1.23  2003/04/25 19:45:41  warmerda
63  * Use special case for full res operations that involve a buffer that is
64  * not packaged (ie. its pixel interleaved).
65  * First implementation of GDALDataset::BlockBasedRasterIO() also added.
66  *
67  * Revision 1.22  2003/03/13 16:34:20  warmerda
68  * another fix in special case rasterio logic
69  *
70  * Revision 1.21  2003/03/13 15:36:59  warmerda
71  * fixed number of words copied in recent IRasterIO() special case
72  *
73  * Revision 1.20  2003/03/09 10:09:15  dron
74  * Speed up improvements in IRasterIO().
75  *
76  * Revision 1.19  2003/02/08 09:33:03  dron
77  * Patch for batch casting removed due to problems.
78  *
79  * Revision 1.18  2003/02/07 16:44:25  dron
80  * IRasterIO() improved to cast several pixels per time.
81  */
82
83 #include "gdal_priv.h"
84
85 CPL_CVSID("$Id$");
86
87 /************************************************************************/
88 /*                             IRasterIO()                              */
89 /*                                                                      */
90 /*      Default internal implementation of RasterIO() ... utilizes      */
91 /*      the Block access methods to satisfy the request.  This would    */
92 /*      normally only be overridden by formats with overviews.          */
93 /************************************************************************/
94
95 CPLErr GDALRasterBand::IRasterIO( GDALRWFlag eRWFlag,
96                                   int nXOff, int nYOff, int nXSize, int nYSize,
97                                   void * pData, int nBufXSize, int nBufYSize,
98                                   GDALDataType eBufType,
99                                   int nPixelSpace, int nLineSpace )
100
101 {
102     int         nBandDataSize = GDALGetDataTypeSize( eDataType ) / 8;
103     int         nBufDataSize = GDALGetDataTypeSize( eBufType ) / 8;
104     GByte       *pabySrcBlock = NULL;
105     GDALRasterBlock *poBlock = NULL;
106     int         nLBlockX=-1, nLBlockY=-1, iBufYOff, iBufXOff, iSrcY;
107
108 /* ==================================================================== */
109 /*      A common case is the data requested with the destination        */
110 /*      is packed, and the block width is the raster width.             */
111 /* ==================================================================== */
112     if( nPixelSpace == nBufDataSize
113         && nLineSpace == nPixelSpace * nXSize
114         && nBlockXSize == GetXSize()
115         && nBufXSize == nXSize
116         && nBufYSize == nYSize )
117     {
118 //        printf( "IRasterIO(%d,%d,%d,%d) rw=%d case 1\n",
119 //                nXOff, nYOff, nXSize, nYSize,
120 //                (int) eRWFlag );
121
122         for( iBufYOff = 0; iBufYOff < nBufYSize; iBufYOff++ )
123         {
124             int         nSrcByteOffset;
125            
126             iSrcY = iBufYOff + nYOff;
127            
128             if( iSrcY < nLBlockY * nBlockYSize
129                 || iSrcY >= (nLBlockY+1) * nBlockYSize )
130             {
131                 nLBlockY = iSrcY / nBlockYSize;
132                 int bJustInitialize =
133                     eRWFlag == GF_Write
134                     && nXOff == 0 && nXSize == nBlockXSize
135                     && nYOff <= nLBlockY * nBlockYSize
136                     && nYOff + nYSize >= (nLBlockY+1) * nBlockYSize;
137
138                 if( poBlock )
139                     poBlock->DropLock();
140
141                 poBlock = GetLockedBlockRef( 0, nLBlockY, bJustInitialize );
142                 if( poBlock == NULL )
143                 {
144                     CPLError( CE_Failure, CPLE_AppDefined,
145                         "GetBlockRef failed at X block offset %d, "
146                         "Y block offset %d", 0, nLBlockY );
147                     return( CE_Failure );
148                 }
149
150                 if( eRWFlag == GF_Write )
151                     poBlock->MarkDirty();
152                
153                 pabySrcBlock = (GByte *) poBlock->GetDataRef();
154             }
155
156             nSrcByteOffset = ((iSrcY-nLBlockY*nBlockYSize)*nBlockXSize + nXOff)
157                 * nBandDataSize;
158            
159             if( eDataType == eBufType )
160             {
161                 if( eRWFlag == GF_Read )
162                     memcpy( ((GByte *) pData) + iBufYOff * nLineSpace,
163                             pabySrcBlock + nSrcByteOffset,
164                             nLineSpace );
165                 else
166                     memcpy( pabySrcBlock + nSrcByteOffset,
167                             ((GByte *) pData) + iBufYOff * nLineSpace,
168                             nLineSpace );
169             }
170             else
171             {
172                 /* type to type conversion */
173                
174                 if( eRWFlag == GF_Read )
175                     GDALCopyWords( pabySrcBlock + nSrcByteOffset,
176                                    eDataType, nBandDataSize,
177                                    ((GByte *) pData) + iBufYOff * nLineSpace,
178                                    eBufType, nPixelSpace, nBufXSize );
179                 else
180                     GDALCopyWords( ((GByte *) pData) + iBufYOff * nLineSpace,
181                                    eBufType, nPixelSpace,
182                                    pabySrcBlock + nSrcByteOffset,
183                                    eDataType, nBandDataSize, nBufXSize );
184             }
185         }
186
187         if( poBlock )
188             poBlock->DropLock();
189
190         return CE_None;
191     }
192    
193 /* ==================================================================== */
194 /*      Do we have overviews that would be appropriate to satisfy       */
195 /*      this request?                                                   */
196 /* ==================================================================== */
197     if( (nBufXSize < nXSize || nBufYSize < nYSize)
198         && GetOverviewCount() > 0 && eRWFlag == GF_Read )
199     {
200         if( OverviewRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
201                               pData, nBufXSize, nBufYSize,
202                               eBufType, nPixelSpace, nLineSpace ) == CE_None )
203             return CE_None;
204     }
205
206 /* ==================================================================== */
207 /*      The second case when we don't need subsample data but likely    */
208 /*      need data type conversion.                                      */
209 /* ==================================================================== */
210     int         iSrcX;
211
212     if ( /* nPixelSpace == nBufDataSize
213             && */ nXSize == nBufXSize
214          && nYSize == nBufYSize )   
215     {
216 //        printf( "IRasterIO(%d,%d,%d,%d) rw=%d case 2\n",
217 //                nXOff, nYOff, nXSize, nYSize,
218 //                (int) eRWFlag );
219
220 /* -------------------------------------------------------------------- */
221 /*      Loop over buffer computing source locations.                    */
222 /* -------------------------------------------------------------------- */
223         int     nLBlockXStart, nXSpanEnd;
224
225         // Calculate starting values out of loop
226         nLBlockXStart = nXOff / nBlockXSize;
227         nXSpanEnd = nBufXSize + nXOff;
228
229         for( iBufYOff = 0, iSrcY = nYOff; iBufYOff < nBufYSize; iBufYOff++, iSrcY++ )
230         {
231             int     iBufOffset, iSrcOffset, nXSpan;
232            
233             iBufOffset = iBufYOff * nLineSpace;
234             nLBlockY = iSrcY / nBlockYSize;
235             nLBlockX = nLBlockXStart;
236             iSrcX = nXOff;
237             while( iSrcX < nXSpanEnd )
238             {
239                 int nXSpanSize;
240
241                 nXSpan = (nLBlockX + 1) * nBlockXSize;
242                 nXSpan = ( ( nXSpan < nXSpanEnd )?nXSpan:nXSpanEnd ) - iSrcX;
243                 nXSpanSize = nXSpan * nPixelSpace;
244
245                 int bJustInitialize =
246                     eRWFlag == GF_Write
247                     && nYOff <= nLBlockY * nBlockYSize
248                     && nYOff + nYSize >= (nLBlockY+1) * nBlockYSize
249                     && nXOff <= nLBlockX * nBlockXSize
250                     && nXOff + nXSize >= (nLBlockX+1) * nBlockXSize;
251
252 //                printf( "bJustInitialize = %d (%d,%d,%d,%d)\n",
253 //                        bJustInitialize,
254 //                        nYOff, nYSize,
255 //                        nLBlockY, nBlockYSize );
256 //                bJustInitialize = FALSE;
257                 
258
259 /* -------------------------------------------------------------------- */
260 /*      Ensure we have the appropriate block loaded.                    */
261 /* -------------------------------------------------------------------- */
262                 poBlock = GetLockedBlockRef( nLBlockX, nLBlockY, bJustInitialize );
263                 if( !poBlock )
264                 {
265                     CPLError( CE_Failure, CPLE_AppDefined,
266                         "GetBlockRef failed at X block offset %d, "
267                         "Y block offset %d", nLBlockX, nLBlockY );
268                     return( CE_Failure );
269                 }
270
271                 if( eRWFlag == GF_Write )
272                     poBlock->MarkDirty();
273                
274                 pabySrcBlock = (GByte *) poBlock->GetDataRef();
275                 if( pabySrcBlock == NULL )
276                 {
277                     poBlock->DropLock();
278                     return CE_Failure;
279                 }
280
281 /* -------------------------------------------------------------------- */
282 /*      Copy over this chunk of data.                                   */
283 /* -------------------------------------------------------------------- */
284                 iSrcOffset = (iSrcX - nLBlockX*nBlockXSize
285                     + (iSrcY - nLBlockY*nBlockYSize) * nBlockXSize)*nBandDataSize;
286
287                 if( eDataType == eBufType
288                     && nPixelSpace == nBufDataSize )
289                 {
290                     if( eRWFlag == GF_Read )
291                         memcpy( ((GByte *) pData) + iBufOffset,
292                                 pabySrcBlock + iSrcOffset, nXSpanSize );
293                     else
294                         memcpy( pabySrcBlock + iSrcOffset,
295                                 ((GByte *) pData) + iBufOffset, nXSpanSize );
296                 }
297                 else
298                 {
299                     /* type to type conversion */
300                    
301                     if( eRWFlag == GF_Read )
302                         GDALCopyWords( pabySrcBlock + iSrcOffset,
303                                        eDataType, nBandDataSize,
304                                        ((GByte *) pData) + iBufOffset,
305                                        eBufType, nPixelSpace, nXSpan );
306                     else
307                         GDALCopyWords( ((GByte *) pData) + iBufOffset,
308                                        eBufType, nPixelSpace,
309                                        pabySrcBlock + iSrcOffset,
310                                        eDataType, nBandDataSize, nXSpan );
311                 }
312
313                 iBufOffset += nXSpanSize;
314                 nLBlockX++;
315                 iSrcX+=nXSpan;
316
317                 poBlock->DropLock();
318                 poBlock = NULL;
319             }
320         }
321
322         return CE_None;
323     }
324
325 /* ==================================================================== */
326 /*      Loop reading required source blocks to satisfy output           */
327 /*      request.  This is the most general implementation.              */
328 /* ==================================================================== */
329
330 /* -------------------------------------------------------------------- */
331 /*      Compute stepping increment.                                     */
332 /* -------------------------------------------------------------------- */
333     double      dfSrcX, dfSrcY, dfSrcXInc, dfSrcYInc;
334 //    int         iSrcX;
335     
336     dfSrcXInc = nXSize / (double) nBufXSize;
337     dfSrcYInc = nYSize / (double) nBufYSize;
338
339 /* -------------------------------------------------------------------- */
340 /*      Loop over buffer computing source locations.                    */
341 /* -------------------------------------------------------------------- */
342 //    printf( "IRasterIO(%d,%d,%d,%d) rw=%d case 3\n",
343 //            nXOff, nYOff, nXSize, nYSize,
344 //            (int) eRWFlag );
345
346     for( iBufYOff = 0; iBufYOff < nBufYSize; iBufYOff++ )
347     {
348         int     iBufOffset, iSrcOffset;
349        
350         dfSrcY = (iBufYOff+0.5) * dfSrcYInc + nYOff;
351         iSrcY = (int) dfSrcY;
352
353         iBufOffset = iBufYOff * nLineSpace;
354        
355         for( iBufXOff = 0; iBufXOff < nBufXSize; iBufXOff++ )
356         {
357             dfSrcX = (iBufXOff+0.5) * dfSrcXInc + nXOff;
358            
359             iSrcX = (int) dfSrcX;
360
361 /* -------------------------------------------------------------------- */
362 /*      Ensure we have the appropriate block loaded.                    */
363 /* -------------------------------------------------------------------- */
364             if( iSrcX < nLBlockX * nBlockXSize
365                 || iSrcX >= (nLBlockX+1) * nBlockXSize
366                 || iSrcY < nLBlockY * nBlockYSize
367                 || iSrcY >= (nLBlockY+1) * nBlockYSize )
368             {
369                 nLBlockX = iSrcX / nBlockXSize;
370                 nLBlockY = iSrcY / nBlockYSize;
371
372                 int bJustInitialize =
373                     eRWFlag == GF_Write
374                     && nYOff <= nLBlockY * nBlockYSize
375                     && nYOff + nYSize >= (nLBlockY+1) * nBlockYSize
376                     && nXOff <= nLBlockX * nBlockXSize
377                     && nXOff + nXSize >= (nLBlockX+1) * nBlockXSize;
378
379                 if( poBlock != NULL )
380                     poBlock->DropLock();
381
382                 poBlock = GetLockedBlockRef( nLBlockX, nLBlockY,
383                                              bJustInitialize );
384                 if( poBlock == NULL )
385                 {
386                     return( CE_Failure );
387                 }
388
389                 if( eRWFlag == GF_Write )
390                     poBlock->MarkDirty();
391                
392                 pabySrcBlock = (GByte *) poBlock->GetDataRef();
393                 if( pabySrcBlock == NULL )
394                 {
395                     poBlock->DropLock();
396                     return CE_Failure;
397                 }
398             }
399
400 /* -------------------------------------------------------------------- */
401 /*      Copy over this pixel of data.                                   */
402 /* -------------------------------------------------------------------- */
403             iSrcOffset = (iSrcX - nLBlockX*nBlockXSize
404                 + (iSrcY - nLBlockY*nBlockYSize) * nBlockXSize)*nBandDataSize;
405
406             if( eDataType == eBufType )
407             {
408                 if( eRWFlag == GF_Read )
409                     memcpy( ((GByte *) pData) + iBufOffset,
410                             pabySrcBlock + iSrcOffset, nBandDataSize );
411                 else
412                     memcpy( pabySrcBlock + iSrcOffset,
413                             ((GByte *) pData) + iBufOffset, nBandDataSize );
414             }
415             else
416             {
417                 /* type to type conversion ... ouch, this is expensive way
418                    of handling single words */
419                
420                 if( eRWFlag == GF_Read )
421                     GDALCopyWords( pabySrcBlock + iSrcOffset, eDataType, 0,
422                                    ((GByte *) pData) + iBufOffset, eBufType, 0,
423                                    1 );
424                 else
425                     GDALCopyWords( ((GByte *) pData) + iBufOffset, eBufType, 0,
426                                    pabySrcBlock + iSrcOffset, eDataType, 0,
427                                    1 );
428             }
429
430             iBufOffset += nPixelSpace;
431         }
432     }
433
434     if( poBlock != NULL )
435         poBlock->DropLock();
436
437     return( CE_None );
438 }
439
440 /************************************************************************/
441 /*                           GDALSwapWords()                            */
442 /************************************************************************/
443
444 /**
445  * Byte swap words in-place.
446  *
447  * This function will byte swap a set of 2, 4 or 8 byte words "in place" in
448  * a memory array.  No assumption is made that the words being swapped are
449  * word aligned in memory.  Use the CPL_LSB and CPL_MSB macros from cpl_port.h
450  * to determine if the current platform is big endian or little endian.  Use
451  * The macros like CPL_SWAP32() to byte swap single values without the overhead
452  * of a function call.
453  *
454  * @param pData pointer to start of data buffer.
455  * @param nWordSize size of words being swapped in bytes. Normally 2, 4 or 8.
456  * @param nWordCount the number of words to be swapped in this call.
457  * @param nWordSkip the byte offset from the start of one word to the start of
458  * the next. For packed buffers this is the same as nWordSize.
459  */
460
461 void CPL_STDCALL GDALSwapWords( void *pData, int nWordSize, int nWordCount,
462                                 int nWordSkip )
463
464 {
465     int         i;
466     GByte       *pabyData = (GByte *) pData;
467
468     switch( nWordSize )
469     {
470       case 1:
471         break;
472
473       case 2:
474         CPLAssert( nWordSkip >= 2 || nWordCount == 1 );
475         for( i = 0; i < nWordCount; i++ )
476         {
477             GByte       byTemp;
478
479             byTemp = pabyData[0];
480             pabyData[0] = pabyData[1];
481             pabyData[1] = byTemp;
482
483             pabyData += nWordSkip;
484         }
485         break;
486        
487       case 4:
488         CPLAssert( nWordSkip >= 4 || nWordCount == 1 );
489         for( i = 0; i < nWordCount; i++ )
490         {
491             GByte       byTemp;
492
493             byTemp = pabyData[0];
494             pabyData[0] = pabyData[3];
495             pabyData[3] = byTemp;
496
497             byTemp = pabyData[1];
498             pabyData[1] = pabyData[2];
499             pabyData[2] = byTemp;
500
501             pabyData += nWordSkip;
502         }
503         break;
504
505       case 8:
506         CPLAssert( nWordSkip >= 8 || nWordCount == 1 );
507         for( i = 0; i < nWordCount; i++ )
508         {
509             GByte       byTemp;
510
511             byTemp = pabyData[0];
512             pabyData[0] = pabyData[7];
513             pabyData[7] = byTemp;
514
515             byTemp = pabyData[1];
516             pabyData[1] = pabyData[6];
517             pabyData[6] = byTemp;
518
519             byTemp = pabyData[2];
520             pabyData[2] = pabyData[5];
521             pabyData[5] = byTemp;
522
523             byTemp = pabyData[3];
524             pabyData[3] = pabyData[4];
525             pabyData[4] = byTemp;
526
527             pabyData += nWordSkip;
528         }
529         break;
530
531       default:
532         CPLAssert( FALSE );
533     }
534 }
535
536 /************************************************************************/
537 /*                           GDALCopyWords()                            */
538 /************************************************************************/
539
540 /**
541  * Copy pixel words from buffer to buffer.
542  *
543  * This function is used to copy pixel word values from one memory buffer
544  * to another, with support for conversion between data types, and differing
545  * step factors.  The data type conversion is done using the normal GDAL
546  * rules.  Values assigned to a lower range integer type are clipped.  For
547  * instance assigning GDT_Int16 values to a GDT_Byte buffer will cause values
548  * less the 0 to be set to 0, and values larger than 255 to be set to 255.
549  * Assignment from floating point to integer uses default C type casting
550  * semantics.   Assignment from non-complex to complex will result in the
551  * imaginary part being set to zero on output.  Assigment from complex to
552  * non-complex will result in the complex portion being lost and the real
553  * component being preserved (<i>not magnitidue!</i>).
554  *
555  * No assumptions are made about the source or destination words occuring
556  * on word boundaries.  It is assumed that all values are in native machine
557  * byte order.
558  *
559  * @param pSrcData
560  *
561  *
562  */
563
564 void CPL_STDCALL
565 GDALCopyWords( void * pSrcData, GDALDataType eSrcType, int nSrcPixelOffset,
566                void * pDstData, GDALDataType eDstType, int nDstPixelOffset,
567                int nWordCount )
568
569 {
570 /* -------------------------------------------------------------------- */
571 /*      Special case when no data type translation is required.         */
572 /* -------------------------------------------------------------------- */
573     if( eSrcType == eDstType )
574     {
575         int     nWordSize = GDALGetDataTypeSize(eSrcType)/8;
576         int     i;
577
578         // contiguous blocks.
579         if( nWordSize == nSrcPixelOffset && nWordSize == nDstPixelOffset )
580         {
581             memcpy( pDstData, pSrcData, nSrcPixelOffset * nWordCount );
582             return;
583         }
584
585         // Moving single bytes, avoid any possible memcpy() overhead.
586         if( nWordSize == 1 )
587         {
588             GByte *pabySrc = (GByte *) pSrcData;
589             GByte *pabyDst = (GByte *) pDstData;
590
591             for( i = nWordCount; i != 0; i-- )
592             {
593                 *pabyDst = *pabySrc;
594                 pabyDst += nDstPixelOffset;
595                 pabySrc += nSrcPixelOffset;
596             }
597             return;
598         }
599
600         // source or destination is not contiguous
601         for( i = 0; i < nWordCount; i++ )
602         {
603             memcpy( ((GByte *)pDstData) + i * nDstPixelOffset,
604                     ((GByte *)pSrcData) + i * nSrcPixelOffset,
605                     nWordSize );
606         }
607
608         return;
609     }
610
611 /* ==================================================================== */
612 /*      General translation case                                        */
613 /* ==================================================================== */
614     for( int iWord = 0; iWord < nWordCount; iWord++ )
615     {
616         void   *pSrcWord, *pDstWord;
617         double  dfPixelValue=0.0, dfPixelValueI=0.0;
618
619         pSrcWord = static_cast<GByte *>(pSrcData) + iWord * nSrcPixelOffset;
620         pDstWord = static_cast<GByte *>(pDstData) + iWord * nDstPixelOffset;
621
622 /* -------------------------------------------------------------------- */
623 /*      Fetch source value based on data type.                          */
624 /* -------------------------------------------------------------------- */
625         switch( eSrcType )
626         {
627           case GDT_Byte:
628           {
629               GByte byVal = *static_cast<GByte *>(pSrcWord);
630               switch( eDstType )
631               {
632                 case GDT_UInt16:
633                   *static_cast<GUInt16 *>(pDstWord) = byVal;
634                   continue;
635                 case GDT_Int16:
636                   *static_cast<GInt16 *>(pDstWord) = byVal;
637                   continue;
638                 case GDT_UInt32:
639                   *static_cast<GUInt32 *>(pDstWord) = byVal;
640                   continue;
641                 case GDT_Int32:
642                   *static_cast<GInt32 *>(pDstWord) = byVal;
643                   continue;
644                 case GDT_CInt16:
645                 {
646                     GInt16 *panDstWord = static_cast<GInt16 *>(pDstWord);
647                     panDstWord[0] = byVal;
648                     panDstWord[1] = 0;
649                     continue;
650                 }
651                 case GDT_CInt32:
652                 {
653                     GInt32 *panDstWord = static_cast<GInt32 *>(pDstWord);
654                     panDstWord[0] = byVal;
655                     panDstWord[1] = 0;
656                     continue;
657                 }
658                 default:
659                   break;
660               }
661               dfPixelValue = byVal;
662           }
663           break;
664
665           case GDT_UInt16:
666           {
667               GUInt16 nVal = *static_cast<GUInt16 *>(pSrcWord);
668               switch( eDstType )
669               {
670                 case GDT_Byte:
671                 {
672                     GByte byVal;
673                     if( nVal > 255 )
674                         byVal = 255;
675                     else
676                         byVal = nVal;
677                     *static_cast<GByte *>(pDstWord) = byVal;
678                     continue;
679                 }
680                 case GDT_Int16:
681                   if( nVal > 32767 )
682                       nVal = 32767;
683                   *static_cast<GInt16 *>(pDstWord) = nVal;
684                   continue;
685                 case GDT_UInt32:
686                   *static_cast<GUInt32 *>(pDstWord) = nVal;
687                   continue;
688                 case GDT_Int32:
689                   *static_cast<GInt32 *>(pDstWord) = nVal;
690                   continue;
691                 case GDT_CInt16:
692                 {
693                     GInt16 *panDstWord = static_cast<GInt16 *>(pDstWord);
694                     if( nVal > 32767 )
695                         nVal = 32767;
696                     panDstWord[0] = nVal;
697                     panDstWord[1] = 0;
698                     continue;
699                 }
700                 case GDT_CInt32:
701                 {
702                     GInt32 *panDstWord = static_cast<GInt32 *>(pDstWord);
703                     panDstWord[0] = nVal;
704                     panDstWord[1] = 0;
705                     continue;
706                 }
707                 default:
708                   break;
709               }
710               dfPixelValue = nVal;
711           }
712           break;
713          
714           case GDT_Int16:
715           {
716               GInt16 nVal = *static_cast<GInt16 *>(pSrcWord);
717               switch( eDstType )
718               {
719                 case GDT_Byte:
720                 {
721                     GByte byVal;
722                     if( nVal > 255 )
723                         byVal = 255;
724                     else if (nVal < 0)
725                         byVal = 0;
726                     else
727                         byVal = nVal;
728                     *static_cast<GByte *>(pDstWord) = byVal;
729                     continue;
730                 }
731                 case GDT_UInt16:
732                   if( nVal < 0 )
733                       nVal = 0;
734                   *static_cast<GUInt16 *>(pDstWord) = nVal;
735                   continue;
736                 case GDT_UInt32:
737                   if( nVal < 0 )
738                       nVal = 0;
739                   *static_cast<GUInt32 *>(pDstWord) = nVal;
740                   continue;
741                 case GDT_Int32:
742                   *static_cast<GInt32 *>(pDstWord) = nVal;
743                   continue;
744                 case GDT_CInt16:
745                 {
746                     GInt16 *panDstWord = static_cast<GInt16 *>(pDstWord);
747                     panDstWord[0] = nVal;
748                     panDstWord[1] = 0;
749                     continue;
750                 }
751                 case GDT_CInt32:
752                 {
753                     GInt32 *panDstWord = static_cast<GInt32 *>(pDstWord);
754                     panDstWord[0] = nVal;
755                     panDstWord[1] = 0;
756                     continue;
757                 }
758                 default:
759                   break;
760               }
761               dfPixelValue = nVal;
762           }
763           break;
764          
765           case GDT_Int32:
766           {
767               GInt32 nVal = *static_cast<GInt32 *>(pSrcWord);
768               switch( eDstType )
769               {
770                 case GDT_Byte:
771                 {
772                     GByte byVal;
773                     if( nVal > 255 )
774                         byVal = 255;
775                     else if (nVal < 0)
776                         byVal = 0;
777                     else
778                         byVal = nVal;
779                     *static_cast<GByte *>(pDstWord) = byVal;
780                     continue;
781                 }
782                 case GDT_UInt16:
783                   if( nVal > 65535 )
784                       nVal = 65535;
785                   else if( nVal < 0 )
786                       nVal = 0;
787                   *static_cast<GUInt16 *>(pDstWord) = nVal;
788                   continue;
789                 case GDT_Int16:
790                   if( nVal > 32767 )
791                       nVal = 32767;
792                   else if( nVal < -32768)
793                       nVal = -32768;
794                   *static_cast<GInt16 *>(pDstWord) = nVal;
795                   continue;
796                 case GDT_UInt32:
797                   if( nVal < 0 )
798                       nVal = 0;
799                   *static_cast<GUInt32 *>(pDstWord) = nVal;
800                   continue;
801                 case GDT_CInt16:
802                 {
803                     GInt16 *panDstWord = static_cast<GInt16 *>(pDstWord);
804                     if( nVal > 32767 )
805                         nVal = 32767;
806                     else if( nVal < -32768)
807                         nVal = -32768;
808                     panDstWord[0] = nVal;
809                     panDstWord[1] = 0;
810                     continue;
811                 }
812                 case GDT_CInt32:
813                 {
814                     GInt32 *panDstWord = static_cast<GInt32 *>(pDstWord);
815                     panDstWord[0] = nVal;
816                     panDstWord[1] = 0;
817                     continue;
818                 }
819                 default:
820                   break;
821               }
822               dfPixelValue = nVal;
823           }
824           break;
825          
826           case GDT_UInt32:
827           {
828               GUInt32 nVal = *static_cast<GUInt32 *>(pSrcWord);
829               switch( eDstType )
830               {
831                 case GDT_Byte:
832                 {
833                     GByte byVal;