PageRenderTime 589ms CodeModel.GetById 293ms app.highlight 268ms RepoModel.GetById 1ms app.codeStats 1ms

/Source/System/Image/WS/OSGImage.cpp

https://github.com/msteners/OpenSGDevMaster_Toolbox
C++ | 4396 lines | 3567 code | 562 blank | 267 comment | 508 complexity | ff0725ce8aebf3f44e101061dc457d17 MD5 | raw file
   1/*---------------------------------------------------------------------------*\
   2 *                                OpenSG                                     *
   3 *                                                                           *
   4 *                                                                           *
   5 *               Copyright (C) 2000-2002 by the OpenSG Forum                 *
   6 *                                                                           *
   7 *                            www.opensg.org                                 *
   8 *                                                                           *
   9 *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
  10 *                                                                           *
  11\*---------------------------------------------------------------------------*/
  12/*---------------------------------------------------------------------------*\
  13 *                                License                                    *
  14 *                                                                           *
  15 * This library is free software; you can redistribute it and/or modify it   *
  16 * under the terms of the GNU Library General Public License as published    *
  17 * by the Free Software Foundation, version 2.                               *
  18 *                                                                           *
  19 * This library is distributed in the hope that it will be useful, but       *
  20 * WITHOUT ANY WARRANTY; without even the implied warranty of                *
  21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
  22 * Library General Public License for more details.                          *
  23 *                                                                           *
  24 * You should have received a copy of the GNU Library General Public         *
  25 * License along with this library; if not, write to the Free Software       *
  26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
  27 *                                                                           *
  28\*---------------------------------------------------------------------------*/
  29/*---------------------------------------------------------------------------*\
  30 *                                Changes                                    *
  31 *                                                                           *
  32 *                                                                           *
  33 *                                                                           *
  34 *                                                                           *
  35 *                                                                           *
  36 *                                                                           *
  37\*---------------------------------------------------------------------------*/
  38
  39#if __GNUC__ >= 4 || __GNUC_MINOR__ >=3
  40#pragma GCC diagnostic warning "-Wsign-compare"
  41#endif
  42
  43#ifdef WIN32
  44#pragma warning( disable : 4018 )
  45#endif
  46
  47//---------------------------------------------------------------------------
  48//  Includes
  49//---------------------------------------------------------------------------
  50
  51#define OSG_COMPILEIMAGE
  52
  53#include <cstdlib>
  54#include <cstdio>
  55
  56#include <algorithm>
  57
  58#include "OSGConfig.h"
  59#include "OSGLog.h"
  60#include "OSGImageGenericAtt.h"
  61#include "OSGFieldContainerFields.h"
  62#include "OSGFileSystem.h"
  63#include "OSGImageFileHandler.h"
  64#include "OSGSquish.h"
  65
  66/*
  67#include "OSGPathHandler.h"
  68#include "OSGSceneFileHandler.h"
  69 */
  70
  71#include "OSGImage.h"
  72
  73OSG_USING_NAMESPACE
  74
  75/*! \class OSG::Image
  76  1D/2D/3D Image with various pixel types data, can also optional hold
  77  mipMap and simple multi-frame data.
  78 */
  79
  80/*------------------------------------------------------------------------*/
  81/*                              static member                             */
  82
  83/*! Static dictionary to map pixelData values to the bytes per pixel
  84  (bpp) value.
  85  Internaly used in the createData() method.
  86 */
  87
  88UInt32 Image::_formatDic[][2] =
  89{
  90    { OSG_A_PF,      1 },
  91    { OSG_I_PF,      1 },
  92    { OSG_L_PF,      1 },
  93    { OSG_LA_PF,     2 },
  94    { OSG_RGB_PF,    3 },
  95    { OSG_RGBA_PF,   4 },
  96    { OSG_BGR_PF,    3 },
  97    { OSG_BGRA_PF,   4 },
  98    { OSG_RGB_DXT1,  3 },
  99    { OSG_RGBA_DXT1, 4 },
 100    { OSG_RGBA_DXT3, 4 },
 101    { OSG_RGBA_DXT5, 4 },
 102    { OSG_ALPHA_INTEGER_PF,           1 },
 103    { OSG_RGB_INTEGER_PF,             3 },
 104    { OSG_RGBA_INTEGER_PF,            4 },
 105    { OSG_BGR_INTEGER_PF,             3 },
 106    { OSG_BGRA_INTEGER_PF,            4 },
 107    { OSG_LUMINANCE_INTEGER_PF,       1 },
 108    { OSG_LUMINANCE_ALPHA_INTEGER_PF, 2 }
 109};
 110
 111Int32 Image::_typeDic[][2] =
 112{
 113    { OSG_INVALID_IMAGEDATATYPE, 0 },
 114    { OSG_UINT8_IMAGEDATA,       1 },
 115    { OSG_UINT16_IMAGEDATA,      2 },
 116    { OSG_UINT32_IMAGEDATA,      4 },
 117    { OSG_FLOAT32_IMAGEDATA,     4 },
 118    { OSG_FLOAT16_IMAGEDATA,     2 },
 119    { OSG_INT16_IMAGEDATA,       2 },
 120    { OSG_INT32_IMAGEDATA,       4 }
 121};
 122
 123/*----------------------------- class specific ----------------------------*/
 124
 125void Image::initMethod(InitPhase ePhase)
 126{
 127}
 128
 129/*! Inform parents, when image was changed
 130 */
 131
 132void Image::changed(ConstFieldMaskArg whichField, 
 133                    UInt32            origin,
 134                    BitVector         details)
 135{
 136    const Image *pThis = this;
 137
 138    MFParentFieldContainerPtr::const_iterator parentsIt  = 
 139        pThis->_mfParents.begin();
 140
 141    MFParentFieldContainerPtr::const_iterator parentsEnd = 
 142        pThis->_mfParents.end();
 143
 144    while(parentsIt != parentsEnd)
 145    {
 146        (*parentsIt)->changed(
 147            TypeTraits<BitVector>::One << parentsIt.getParentFieldPos(),
 148            ChangedOrigin::Child,
 149            whichField);
 150
 151        ++parentsIt;
 152    }
 153
 154    if(0x0000 != (whichField & DataTypeFieldMask))
 155    {
 156        // Update internals
 157        Int32 mapSizeType = sizeof(_typeDic) / sizeof(UInt32[2]);
 158        UInt32 typeFormat  = 0;
 159        Int32 i;
 160        
 161        for(i = 0; i < mapSizeType; i++)
 162        {
 163            if(_typeDic[i][0] == _sfDataType.getValue())
 164            {
 165                typeFormat = _typeDic[i][1];
 166            }
 167        }
 168        
 169        setComponentSize( typeFormat );
 170    }
 171
 172    if(0x0000 != (whichField & (MipMapCountFieldMask |
 173                                WidthFieldMask       |
 174                                HeightFieldMask      |
 175                                DepthFieldMask       |
 176                                PixelFormatFieldMask )))
 177    {
 178        setSideSize(calcMipmapSumSize(_sfMipMapCount.getValue()));
 179    }
 180
 181    if(0x0000 != (whichField & (SideSizeFieldMask | SideCountFieldMask)))
 182    {
 183        setFrameSize(_sfSideSize.getValue() * _sfSideCount.getValue());
 184    }
 185
 186    calcMipmapOffsets();
 187
 188    Inherited::changed(whichField, origin, details);
 189}
 190
 191/*----------------------------- output ------------------------------------*/
 192
 193void Image::dump(      UInt32    ,
 194                 const BitVector ) const
 195{
 196    const Char8  *pfStr   = "UNDEF_PIXEL_FORMAT";
 197    const Char8  *typeStr = "INVALID_IMAGEDATA_TYPE";
 198
 199    switch(getPixelFormat())
 200    {
 201        case OSG_A_PF:
 202            pfStr = "ALPHA";
 203            break;
 204        case OSG_I_PF:
 205            pfStr = "INTENSITY";
 206            break;
 207        case OSG_L_PF:
 208            pfStr = "LUMINANCE";
 209            break;
 210        case OSG_LA_PF:
 211            pfStr = "LUMINANCE_ALPHA";
 212            break;
 213        case OSG_BGR_PF:
 214            pfStr = "BGR";
 215            break;
 216        case OSG_BGRA_PF:
 217            pfStr = "BGRA";
 218            break;
 219        case OSG_RGB_PF:
 220            pfStr = "RGB";
 221            break;
 222        case OSG_RGBA_PF:
 223            pfStr = "RGBA";
 224            break;
 225        case OSG_RGB_DXT1:
 226            pfStr = "RGB_DXT1";
 227            break;
 228        case OSG_RGBA_DXT1:
 229            pfStr = "RGBA_DXT1";
 230            break;
 231        case OSG_RGBA_DXT3:
 232            pfStr = "RGBA_DXT3";
 233            break;
 234        case OSG_RGBA_DXT5:
 235            pfStr = "RGBA_DXT5";
 236            break;
 237        case OSG_ALPHA_INTEGER_PF:
 238            pfStr = "ALPHA_INTEGER";
 239            break;
 240        case OSG_RGB_INTEGER_PF:
 241            pfStr = "RGB_INTEGER";
 242            break;
 243        case OSG_RGBA_INTEGER_PF:
 244            pfStr = "RGBA_INTEGER";
 245            break;
 246        case OSG_BGR_INTEGER_PF:
 247            pfStr = "BGR_INTEGER";
 248            break;
 249        case OSG_BGRA_INTEGER_PF:
 250            pfStr = "BGRA_INTEGER";
 251            break;
 252        case OSG_LUMINANCE_INTEGER_PF:
 253            pfStr = "LUMINANCE_INTEGER";
 254            break;
 255        case OSG_LUMINANCE_ALPHA_INTEGER_PF:
 256            pfStr = "LUMINANCE_ALPHA_INTEGER";
 257            break;
 258        default:
 259            pfStr = "UNKNOWN_PIXEL_FORMAT";
 260            break;
 261    };
 262
 263    switch (getDataType())
 264    {
 265        case OSG_UINT8_IMAGEDATA:
 266            typeStr = "IMAGEDATA_TYPE UCHAR8";
 267            break;
 268        case OSG_UINT16_IMAGEDATA:
 269            typeStr = "IMAGEDATA_TYPE UCHAR16";
 270            break;
 271        case OSG_UINT32_IMAGEDATA:
 272            typeStr = "IMAGEDATA_TYPE UCHAR32";
 273            break;
 274        case OSG_FLOAT16_IMAGEDATA:
 275            typeStr = "IMAGEDATA_TYPE FLOAT16";
 276            break;
 277        case OSG_FLOAT32_IMAGEDATA:
 278            typeStr = "IMAGEDATA_TYPE FLOAT32";
 279            break;
 280        case OSG_INT16_IMAGEDATA:
 281            typeStr = "IMAGEDATA_TYPE INT16";
 282            break;
 283        case OSG_INT32_IMAGEDATA:
 284            typeStr = "IMAGEDATA_TYPE INT32";
 285            break;
 286
 287        default:
 288            typeStr = "UNKNOWN_IMAGEDATA_TYPE";
 289            break;
 290    };
 291
 292    FLOG (("ImageDump: %s; %d/%d/%d; #mm: %d, side %d, #frame: %d, "
 293           "frameDelay %g, dataType %s, size: %ld\n",
 294           pfStr,
 295           getWidth(),
 296           getHeight(),
 297           getDepth(),
 298           getMipMapCount(),
 299           getSideCount(),
 300           getFrameCount(),
 301           getFrameDelay(),
 302           typeStr,
 303           getSize()));
 304}
 305
 306// Return the number of components per pixel.
 307
 308UInt8  Image::getComponents(void) const
 309{
 310    UInt16 mapSizeFormat = sizeof(_formatDic) / sizeof(UInt32[2]);
 311
 312    for(UInt16 i = 0; i < mapSizeFormat; i++)
 313    {
 314        if(_formatDic[i][0] == getPixelFormat())
 315            return _formatDic[i][1];
 316    }
 317
 318    FWARNING(("Image::getComponents: image %p has unknown pixel format 0x%x!",
 319                this, getPixelFormat()));
 320
 321    return 0;
 322}
 323
 324/*------------------------------ set object data --------------------------*/
 325
 326/*! method to set the image data. Use the doCopy parameter to specify, whether
 327    the method should copy or link the pixel data.
 328*/
 329bool Image::set(      UInt32  pF,
 330                      Int32   w,
 331                      Int32   h,
 332                      Int32   d,
 333                      Int32   mmS,
 334                      Int32   fS,
 335                      Time    fD,
 336                const UChar8 *da,
 337                      Int32   t,
 338                      bool    allocMem,
 339                      Int32   sS)
 340{
 341    setPixelFormat(pF );
 342
 343    setWidth      (osgMax ( 1, w  ));
 344    setHeight     (osgMax ( 1, h  ));
 345    setDepth      (osgMax ( 1, d  ));
 346
 347    setMipMapCount(osgMax ( 1, mmS));
 348    setSideCount  (osgMax ( 1, sS ));
 349    setFrameCount (osgMax ( 1, fS ));
 350
 351    setFrameDelay (fD);
 352
 353    setDataType   (t );
 354
 355    calcMipmapOffsets();
 356
 357    return createData(da, allocMem);
 358}
 359
 360/*! method to set the image from another image object.
 361    Use the doCopy parameter to specify, whether
 362    the method should copy or link the pixel data.
 363 */
 364
 365bool Image::set(Image *image)
 366{
 367    this->set(image->getPixelFormat(),
 368              image->getWidth      (),
 369              image->getHeight     (),
 370              image->getDepth      (),
 371              image->getMipMapCount(),
 372              image->getFrameCount (),
 373              image->getFrameDelay (),
 374              image->getData       (),
 375              image->getDataType   (),
 376              true,
 377              image->getSideCount  ());
 378    return true;
 379}
 380
 381/*! method to set only the image pixel data, all parameter (e. pixelFormat
 382    width,height and depth) stay the same
 383 */
 384
 385bool Image::setData(const UChar8 *da)
 386{
 387    if(da)
 388    {
 389        createData(da);
 390    }
 391    else
 392    {
 393        FWARNING(("Image::setData(Null) call\n"));
 394    }
 395
 396    return (da ? true : false);
 397}
 398
 399void Image::clearData(void)
 400{
 401    editMFPixel()->clear();
 402}
 403
 404/*! method to update just a subregion of the image data
 405  all paramter (e. pixelFormat,width,height,depth) stay the same
 406*/
 407bool Image::setSubData(      Int32  offX,
 408                             Int32  offY,
 409                             Int32  offZ,
 410                             Int32  srcW,
 411                             Int32  srcH,
 412                             Int32  srcD,
 413                       const UInt8 *src )
 414{
 415    UChar8 *dest = editData();
 416    UInt64  lineSize;
 417
 418    FDEBUG(( "Image::setSubData (%d %d %d) - (%d %d %d) - src %p\n",
 419             offX, offY, offZ, srcW, srcH, srcD, src ));
 420
 421    if (hasCompressedData())
 422    {
 423        FFATAL (("Invalid Image::setSubData for compressed image\n"));
 424        return false;
 425    }
 426
 427    if(!src || !dest)
 428    {
 429        FFATAL(("Invalid data pointer in Image::setSubData\n"));
 430        return false;
 431    }
 432
 433    // determine the area to actually copy
 434    UInt32 xMin = osgMax(0, offX);
 435    UInt32 yMin = osgMax(0, offY);
 436    UInt32 zMin = osgMax(0, offZ);
 437
 438    UInt32 xMax = osgMin(getWidth (), offX + srcW);
 439    UInt32 yMax = osgMin(getHeight(), offY + srcH);
 440    UInt32 zMax = osgMin(getDepth (), offZ + srcD);
 441
 442    // fill the destination buffer with the subdata
 443    UInt32 destIdx, srcIdx = 0;
 444
 445    for(UInt32 z = zMin; z < zMax; z++)
 446    {
 447        for(UInt32 y = yMin; y < yMax; y++)
 448        {
 449            lineSize = (xMax - xMin) * getBpp();
 450            destIdx  = ((z * getHeight() + y) * getWidth() + xMin) * getBpp();
 451
 452            memcpy (&dest[destIdx], &src[srcIdx], size_t(lineSize));
 453
 454            srcIdx  += Int32((srcW - (xMax - xMin)) * getBpp() + lineSize);
 455        }
 456        srcIdx += (srcH - (yMax - yMin)) * srcW * getBpp();
 457    }
 458
 459    return true;
 460}
 461
 462/*! The Image is not just a 2D container. The class can hold 3D (volume)
 463    and movie data. If we have 3D/singleFrame or 2D/multiFrame data without
 464    mipmaps we can flip between this two formats by just swapping the
 465    getFrameCount() and getDepth() values.
 466*/
 467bool Image::flipDepthFrameData(void)
 468{
 469    bool  retCode = false;
 470    Int32 value;
 471
 472    if((getMipMapCount() == 1) &&
 473       ((getFrameCount() == 1) || (getDepth() == 1)))
 474    {
 475        value = getFrameCount();
 476
 477        setFrameCount(getDepth());
 478        setDepth     (value     );
 479
 480        retCode = true;
 481    }
 482    else
 483    {
 484      FWARNING (("Cant flipDepthFrameData(); invalid data layout\n"));
 485    }
 486
 487    return retCode;
 488}
 489
 490/*! This method is used by the parser to fill the image with
 491    string pixel data. It expects the data in VRML PixelTexture Format.
 492*/
 493bool Image::addValue(const char *value)
 494{
 495    static Image  *currentImage = 0;
 496    static UChar8 *currentData  = 0;
 497
 498           Int64   j;
 499           Int64   v;
 500
 501           bool    isHead = strchr(value, ' ') ? true : false;
 502
 503    if (hasCompressedData())
 504    {
 505        FFATAL (("Invalid Image::addValue for compressed image\n"));
 506        return false;
 507    }
 508
 509    // make sure we only read one image at a time
 510    if(currentImage == this)
 511    {
 512        if(isHead)
 513        {
 514            FDEBUG(("Start new read cycle in image::addValue()\n"));
 515        }
 516    }
 517    else
 518    {
 519        if(!isHead)
 520        {
 521            FFATAL(("Additional image date for different image\n"));
 522        }
 523    }
 524
 525    currentImage = this;
 526
 527    if(isHead == true)
 528    {
 529        Int32        width;
 530        Int32        height;
 531        Int32        pixelDepth;
 532        PixelFormat  pf         = Image::OSG_INVALID_PF;
 533
 534        // read the head
 535        sscanf(value, "%d %d %d", &width, &height, &pixelDepth);
 536
 537        FDEBUG(("Image::addValue() set: w/h/bpp: %d/%d/%d\n",
 538                width, height, pixelDepth));
 539
 540        switch(getDataType())
 541        {
 542            case OSG_UINT8_IMAGEDATA:
 543                switch(pixelDepth)
 544                {
 545                    case 1:
 546                        pf = OSG::Image::OSG_L_PF;
 547                        break;
 548                    case 2:
 549                        pf = OSG::Image::OSG_LA_PF;
 550                        break;
 551                    case 3:
 552                        pf = OSG::Image::OSG_RGB_PF;
 553                        break;
 554                    case 4:
 555                        pf = OSG::Image::OSG_RGBA_PF;
 556                        break;
 557                    default:
 558                        pf = OSG::Image::OSG_INVALID_PF;
 559                        FFATAL(("Invalid pixel depth: %d\n", pixelDepth));
 560                        break;
 561                }
 562                break;
 563
 564            case OSG_UINT16_IMAGEDATA:
 565                switch(pixelDepth)
 566                {
 567                    case 2:
 568                        pf = OSG::Image::OSG_L_PF;
 569                        break;
 570                    case 4:
 571                        pf = OSG::Image::OSG_LA_PF;
 572                        break;
 573                    case 6:
 574                        pf = OSG::Image::OSG_RGB_PF;
 575                        break;
 576                    case 8:
 577                        pf = OSG::Image::OSG_RGBA_PF;
 578                        break;
 579                    default:
 580                        pf = OSG::Image::OSG_INVALID_PF;
 581                        FFATAL(("Invalid pixel depth: %d\n", pixelDepth));
 582                        break;
 583                }
 584                break;
 585
 586            case OSG_UINT32_IMAGEDATA:
 587                switch(pixelDepth)
 588                {
 589                    case 4:
 590                        pf = OSG::Image::OSG_L_PF;
 591                        break;
 592                    case 8:
 593                        pf = OSG::Image::OSG_LA_PF;
 594                        break;
 595                    case 12:
 596                        pf = OSG::Image::OSG_RGB_PF;
 597                        break;
 598                    case 16:
 599                        pf = OSG::Image::OSG_RGBA_PF;
 600                        break;
 601                    default:
 602                        pf = OSG::Image::OSG_INVALID_PF;
 603                        FFATAL(("Invalid pixel depth: %d\n", pixelDepth));
 604                        break;
 605                }
 606                break;
 607
 608            case OSG_FLOAT32_IMAGEDATA:
 609                switch(pixelDepth)
 610                {
 611                    case 4:
 612                        pf = OSG::Image::OSG_L_PF;
 613                        break;
 614                    case 8:
 615                        pf = OSG::Image::OSG_LA_PF;
 616                        break;
 617                    case 12:
 618                        pf = OSG::Image::OSG_RGB_PF;
 619                        break;
 620                    case 16:
 621                        pf = OSG::Image::OSG_RGBA_PF;
 622                        break;
 623                    default:
 624                        pf = OSG::Image::OSG_INVALID_PF;
 625                        FFATAL(("Invalid pixel depth: %d\n", pixelDepth));
 626                        break;
 627                }
 628                break;
 629
 630            case OSG_FLOAT16_IMAGEDATA:
 631                switch(pixelDepth)
 632                {
 633                    case 2:
 634                        pf = OSG::Image::OSG_L_PF;
 635                        break;
 636                    case 4:
 637                        pf = OSG::Image::OSG_LA_PF;
 638                        break;
 639                    case 6:
 640                        pf = OSG::Image::OSG_RGB_PF;
 641                        break;
 642                    case 8:
 643                        pf = OSG::Image::OSG_RGBA_PF;
 644                        break;
 645                    default:
 646                        pf = OSG::Image::OSG_INVALID_PF;
 647                        FFATAL(("Invalid pixel depth: %d\n", pixelDepth));
 648                        break;
 649                }
 650                break;
 651
 652			case OSG_INT16_IMAGEDATA:
 653			case OSG_INT32_IMAGEDATA:
 654            {
 655                FFATAL((" 'addValue' NYI\n "));
 656            }
 657            break;
 658
 659            default:
 660                setDataType(OSG_INVALID_IMAGEDATATYPE);
 661                FFATAL(("Invalid type of image data: %d\n", getDataType()));
 662        }
 663
 664        if(pf != 0 && (width > 0) && (height > 0))
 665        {
 666            set(pf, width, height);
 667
 668            currentData = editData();
 669        }
 670        else
 671        {
 672            currentData = NULL;
 673        }
 674    }
 675    else
 676    {
 677        if(currentData != NULL)
 678        {
 679            // add data
 680            // TODO; should we check the bounds, should be done by the parser
 681
 682            v = strtoul(value, 0, strchr(value, 'x') ? 16 : 10);
 683
 684            for(j = getBpp(); j--;)
 685            {
 686                *currentData++ = UChar8( (v >> (8 * j)) & 255 );
 687            }
 688
 689        }
 690    }
 691
 692    return currentData ? true : false;
 693}
 694
 695/*! It is a simple method to reformat the image pixelFormat (not the size).
 696    So you can for example convert a RGBA to RGB or RGB to Grey image.
 697*/
 698bool Image::reformat(const Image::PixelFormat  pixelFormat,
 699                           Image              *destination,
 700                           Int32               iCompressionFlags)
 701{
 702          UChar8   *data       = NULL;
 703    const UChar8   *sourceData = NULL;
 704          UInt32    srcI, destI, destSize = 0;
 705          UInt32         sum;
 706          Real64         sumReal;
 707          ImageUnrecPtr  dest(destination);
 708
 709    if (hasCompressedData())
 710    {
 711        FFATAL (("Invalid Image::reformat for compressed image\n"));
 712        return false;
 713    }
 714
 715    if(destination == NULL)
 716    {
 717        dest = Image::create();
 718    }
 719
 720    FINFO(("Try to reformat image from pixelDepth %d to %d\n",
 721           getPixelFormat(),
 722           pixelFormat    ));
 723
 724    if(iCompressionFlags == 0)
 725    {
 726        iCompressionFlags = (osgsquish::kColourMetricPerceptual | 
 727                             osgsquish::kColourRangeFit         );
 728    }
 729
 730    iCompressionFlags &= ~0x07;
 731
 732    // TODO !!! code all the cases !!!
 733
 734    if(getSize()    != 0              &&
 735       pixelFormat  != OSG_INVALID_PF &&
 736       (destination != 0 || (pixelFormat != static_cast<Image::PixelFormat>(getPixelFormat()))))
 737    {
 738
 739        dest->set(pixelFormat, 
 740                  getWidth      (), 
 741                  getHeight     (), 
 742                  getDepth      (), 
 743                  getMipMapCount(),
 744                  getFrameCount (), 
 745                  getFrameDelay (), 
 746                  NULL, 
 747                  getDataType   (), 
 748                  true, 
 749                  getSideCount  ());
 750
 751        sourceData = getData();
 752
 753        data       = dest->editData();
 754        destSize   = dest->getSize();
 755
 756        const UInt16 *sourceDataUC16 = 
 757            reinterpret_cast<const UInt16 *>(sourceData);
 758
 759              UInt16 *destDataUC16   = reinterpret_cast<UInt16 *>(data);
 760
 761        const UInt32 *sourceDataUC32 = 
 762            reinterpret_cast<const UInt32 *>(sourceData);
 763
 764              UInt32 *destDataUC32   = reinterpret_cast<UInt32 *>(data);
 765
 766        const Real32 *sourceDataF32  = 
 767            reinterpret_cast<const Real32 *>(sourceData);
 768
 769              Real32 *destDataF32    = reinterpret_cast<Real32 *>(data);
 770
 771        const Real16 *sourceDataH16  = 
 772            reinterpret_cast<const Real16 *>(sourceData);
 773
 774              Real16 *destDataH16    = reinterpret_cast<Real16 *>(data);
 775
 776        if(data)
 777        {
 778            switch (getPixelFormat())
 779            {
 780                //-----------------------------------------------------
 781                case OSG_A_PF:
 782                    switch (pixelFormat) 
 783                    {
 784                        case OSG_A_PF:
 785                        case OSG_I_PF:
 786                        case OSG_L_PF:
 787                            switch (getDataType())
 788                            {
 789                                case OSG_UINT8_IMAGEDATA:
 790                                case OSG_UINT16_IMAGEDATA:
 791                                case OSG_UINT32_IMAGEDATA:
 792                                case OSG_FLOAT32_IMAGEDATA:
 793                                case OSG_FLOAT16_IMAGEDATA:
 794                                    memcpy (data, getData(), destSize);
 795                                    break;
 796                                    
 797                                default:
 798                                    FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
 799                                break;
 800                            }
 801                            break;
 802
 803                        case OSG_LA_PF:
 804                            switch (getDataType())
 805                            {
 806                                case OSG_UINT8_IMAGEDATA:
 807                                    for (srcI = destI = 0; destI < destSize;)
 808                                    {
 809                                        data[destI++] = sourceData[srcI];
 810                                        data[destI++] = sourceData[srcI++];
 811                                    }
 812                                    break;
 813                                case OSG_UINT16_IMAGEDATA:
 814                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
 815                                    {
 816                                        destDataUC16[destI++] = sourceDataUC16[srcI];
 817                                        destDataUC16[destI++] = sourceDataUC16[srcI++];
 818                                    }
 819                                    break;
 820                                case OSG_UINT32_IMAGEDATA:
 821                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
 822                                    {
 823                                        destDataUC32[destI++] = sourceDataUC32[srcI];
 824                                        destDataUC32[destI++] = sourceDataUC32[srcI++];
 825                                    }
 826                                    break;
 827                                case OSG_FLOAT32_IMAGEDATA:
 828                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
 829                                    {
 830                                        destDataF32[destI++] = sourceDataF32[srcI];
 831                                        destDataF32[destI++] = sourceDataF32[srcI++];
 832                                    }
 833                                    break;
 834                                    
 835                                case OSG_FLOAT16_IMAGEDATA:
 836                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
 837                                    {
 838                                        destDataH16[destI++] = sourceDataH16[srcI];
 839                                        destDataH16[destI++] = sourceDataH16[srcI++];
 840                                    }
 841                                    break;
 842                                default:
 843                                    FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
 844                                    break;
 845                            }
 846                            break;
 847                            
 848                        case OSG_RGB_PF:
 849                            switch (getDataType())
 850                            {
 851                                case OSG_UINT8_IMAGEDATA:
 852                                    for (srcI = destI = 0; destI < destSize;)
 853                                    {
 854                                        data[destI++] = sourceData[srcI];
 855                                        data[destI++] = sourceData[srcI];
 856                                        data[destI++] = sourceData[srcI++];
 857                                    }
 858                                    break;
 859                                case OSG_UINT16_IMAGEDATA:
 860                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
 861                                    {
 862                                        destDataUC16[destI++] = sourceDataUC16[srcI];
 863                                        destDataUC16[destI++] = sourceDataUC16[srcI];
 864                                        destDataUC16[destI++] = sourceDataUC16[srcI++];
 865                                    }
 866                                    break;
 867                                case OSG_UINT32_IMAGEDATA:
 868                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
 869                                    {
 870                                        destDataUC32[destI++] = sourceDataUC32[srcI];
 871                                        destDataUC32[destI++] = sourceDataUC32[srcI];
 872                                        destDataUC32[destI++] = sourceDataUC32[srcI++];
 873                                    }
 874                                    break;
 875                                case OSG_FLOAT32_IMAGEDATA:
 876                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
 877                                    {
 878                                        destDataF32[destI++] = sourceDataF32[srcI];
 879                                        destDataF32[destI++] = sourceDataF32[srcI];
 880                                        destDataF32[destI++] = sourceDataF32[srcI++];
 881                                    }
 882                                    break;
 883                                case OSG_FLOAT16_IMAGEDATA:
 884                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
 885                                    {
 886                                        destDataH16[destI++] = sourceDataH16[srcI];
 887                                        destDataH16[destI++] = sourceDataH16[srcI];
 888                                        destDataH16[destI++] = sourceDataH16[srcI++];
 889                                    }
 890                                    break;
 891                                default:
 892                                    FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
 893                                    break;
 894                            }
 895                            break;
 896                            
 897                        case OSG_RGBA_PF:
 898                            switch (getDataType())
 899                            {
 900                                case OSG_UINT8_IMAGEDATA:
 901                                    for (srcI = destI = 0; destI < destSize;)
 902                                    {
 903                                        data[destI++] = sourceData[srcI];
 904                                    data[destI++] = sourceData[srcI];
 905                                    data[destI++] = sourceData[srcI];
 906                                    data[destI++] = sourceData[srcI++];
 907                                }
 908                                break;
 909                            case OSG_UINT16_IMAGEDATA:
 910                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
 911                                {
 912                                    destDataUC16[destI++] = sourceDataUC16[srcI];
 913                                    destDataUC16[destI++] = sourceDataUC16[srcI];
 914                                    destDataUC16[destI++] = sourceDataUC16[srcI];
 915                                    destDataUC16[destI++] = sourceDataUC16[srcI++];
 916                                }
 917                                break;
 918                            case OSG_UINT32_IMAGEDATA:
 919                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
 920                                {
 921                                    destDataUC32[destI++] = sourceDataUC32[srcI];
 922                                    destDataUC32[destI++] = sourceDataUC32[srcI];
 923                                    destDataUC32[destI++] = sourceDataUC32[srcI];
 924                                    destDataUC32[destI++] = sourceDataUC32[srcI++];
 925                                }
 926                                break;
 927                            case OSG_FLOAT32_IMAGEDATA:
 928                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
 929                                {
 930                                    destDataF32[destI++] = sourceDataF32[srcI];
 931                                    destDataF32[destI++] = sourceDataF32[srcI];
 932                                    destDataF32[destI++] = sourceDataF32[srcI];
 933                                    destDataF32[destI++] = sourceDataF32[srcI++];
 934                                }
 935                                break;
 936                            case OSG_FLOAT16_IMAGEDATA:
 937                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
 938                                {
 939                                    destDataH16[destI++] = sourceDataH16[srcI];
 940                                    destDataH16[destI++] = sourceDataH16[srcI];
 941                                    destDataH16[destI++] = sourceDataH16[srcI];
 942                                    destDataH16[destI++] = sourceDataH16[srcI++];
 943                                }
 944                                break;
 945                            default:
 946                                FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
 947                                break;
 948                            }
 949                            break;
 950                    default:
 951                        FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
 952                        break;
 953                    }
 954                    break;
 955
 956                //-----------------------------------------------------
 957                case OSG_I_PF:
 958                    switch (pixelFormat) 
 959                    {
 960                        case OSG_A_PF:
 961                        case OSG_I_PF:
 962                        case OSG_L_PF:
 963                            switch (getDataType())
 964                            {
 965                            case OSG_UINT8_IMAGEDATA:
 966                                memcpy (data, getData(), destSize);
 967                                break;
 968                            case OSG_UINT16_IMAGEDATA:
 969                                memcpy (data, getData(), destSize);
 970                                break;
 971                            case OSG_UINT32_IMAGEDATA:
 972                                memcpy (data, getData(), destSize);
 973                                break;
 974                            case OSG_FLOAT32_IMAGEDATA:
 975                                memcpy (data, getData(), destSize);
 976                                break;
 977                            case OSG_FLOAT16_IMAGEDATA:
 978                                memcpy (data, getData(), destSize);
 979                                break;
 980
 981                            default:
 982                                FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
 983                                break;
 984                            }
 985                            break;
 986
 987                        case OSG_LA_PF:
 988                            switch (getDataType())
 989                            {
 990                            case OSG_UINT8_IMAGEDATA:
 991                                for (srcI = destI = 0; destI < destSize;)
 992                                {
 993                                    data[destI++] = sourceData[srcI];
 994                                    data[destI++] = sourceData[srcI++];
 995                                }
 996                                break;
 997                            case OSG_UINT16_IMAGEDATA:
 998                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
 999                                {
1000                                    destDataUC16[destI++] = sourceDataUC16[srcI];
1001                                    destDataUC16[destI++] = sourceDataUC16[srcI++];
1002                                }
1003                                break;
1004                            case OSG_UINT32_IMAGEDATA:
1005                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1006                                {
1007                                    destDataUC32[destI++] = sourceDataUC32[srcI];
1008                                    destDataUC32[destI++] = sourceDataUC32[srcI++];
1009                                }
1010                                break;
1011                            case OSG_FLOAT32_IMAGEDATA:
1012                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1013                                {
1014                                    destDataF32[destI++] = sourceDataF32[srcI];
1015                                    destDataF32[destI++] = sourceDataF32[srcI++];
1016                                }
1017                                break;
1018
1019                            case OSG_FLOAT16_IMAGEDATA:
1020                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1021                                {
1022                                    destDataH16[destI++] = sourceDataH16[srcI];
1023                                    destDataH16[destI++] = sourceDataH16[srcI++];
1024                                }
1025                                break;
1026                            default:
1027                                FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1028                                break;
1029                            }
1030                            break;
1031
1032                        case OSG_RGB_PF:
1033                            switch (getDataType())
1034                            {
1035                            case OSG_UINT8_IMAGEDATA:
1036                                for (srcI = destI = 0; destI < destSize;)
1037                                {
1038                                    data[destI++] = sourceData[srcI];
1039                                    data[destI++] = sourceData[srcI];
1040                                    data[destI++] = sourceData[srcI++];
1041                                }
1042                                break;
1043                            case OSG_UINT16_IMAGEDATA:
1044                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1045                                {
1046                                    destDataUC16[destI++] = sourceDataUC16[srcI];
1047                                    destDataUC16[destI++] = sourceDataUC16[srcI];
1048                                    destDataUC16[destI++] = sourceDataUC16[srcI++];
1049                                }
1050                                break;
1051                            case OSG_UINT32_IMAGEDATA:
1052                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1053                                {
1054                                    destDataUC32[destI++] = sourceDataUC32[srcI];
1055                                    destDataUC32[destI++] = sourceDataUC32[srcI];
1056                                    destDataUC32[destI++] = sourceDataUC32[srcI++];
1057                                }
1058                                break;
1059                            case OSG_FLOAT32_IMAGEDATA:
1060                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1061                                {
1062                                    destDataF32[destI++] = sourceDataF32[srcI];
1063                                    destDataF32[destI++] = sourceDataF32[srcI];
1064                                    destDataF32[destI++] = sourceDataF32[srcI++];
1065                                }
1066                                break;
1067                            case OSG_FLOAT16_IMAGEDATA:
1068                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1069                                {
1070                                    destDataH16[destI++] = sourceDataH16[srcI];
1071                                    destDataH16[destI++] = sourceDataH16[srcI];
1072                                    destDataH16[destI++] = sourceDataH16[srcI++];
1073                                }
1074                                break;
1075                            default:
1076                                FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1077                                break;
1078                            }
1079                            break;
1080
1081                        case OSG_RGBA_PF:
1082                            switch (getDataType())
1083                            {
1084                            case OSG_UINT8_IMAGEDATA:
1085                                for (srcI = destI = 0; destI < destSize;)
1086                                {
1087                                    data[destI++] = sourceData[srcI];
1088                                    data[destI++] = sourceData[srcI];
1089                                    data[destI++] = sourceData[srcI];
1090                                    data[destI++] = sourceData[srcI++];
1091                                }
1092                                break;
1093                            case OSG_UINT16_IMAGEDATA:
1094                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1095                                {
1096                                    destDataUC16[destI++] = sourceDataUC16[srcI];
1097                                    destDataUC16[destI++] = sourceDataUC16[srcI];
1098                                    destDataUC16[destI++] = sourceDataUC16[srcI];
1099                                    destDataUC16[destI++] = sourceDataUC16[srcI++];
1100                                }
1101                                break;
1102                            case OSG_UINT32_IMAGEDATA:
1103                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1104                                {
1105                                    destDataUC32[destI++] = sourceDataUC32[srcI];
1106                                    destDataUC32[destI++] = sourceDataUC32[srcI];
1107                                    destDataUC32[destI++] = sourceDataUC32[srcI];
1108                                    destDataUC32[destI++] = sourceDataUC32[srcI++];
1109                                }
1110                                break;
1111                            case OSG_FLOAT32_IMAGEDATA:
1112                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1113                                {
1114                                    destDataF32[destI++] = sourceDataF32[srcI];
1115                                    destDataF32[destI++] = sourceDataF32[srcI];
1116                                    destDataF32[destI++] = sourceDataF32[srcI];
1117                                    destDataF32[destI++] = sourceDataF32[srcI++];
1118                                }
1119                                break;
1120                            case OSG_FLOAT16_IMAGEDATA:
1121                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1122                                {
1123                                    destDataH16[destI++] = sourceDataH16[srcI];
1124                                    destDataH16[destI++] = sourceDataH16[srcI];
1125                                    destDataH16[destI++] = sourceDataH16[srcI];
1126                                    destDataH16[destI++] = sourceDataH16[srcI++];
1127                                }
1128                                break;
1129                            default:
1130                                FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1131                                break;
1132                            }
1133                            break;
1134                    default:
1135                        FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1136                        break;
1137                    }
1138                    break;
1139
1140
1141                //-----------------------------------------------------
1142                case OSG_L_PF:
1143                    switch (pixelFormat) 
1144                    {
1145                        case OSG_A_PF:
1146                        case OSG_I_PF:
1147                        case OSG_L_PF:
1148                            switch (getDataType())
1149                            {
1150                            case OSG_UINT8_IMAGEDATA:
1151                                memcpy (data, getData(), destSize);
1152                                break;
1153                            case OSG_UINT16_IMAGEDATA:
1154                                memcpy (data, getData(), destSize);
1155                                break;
1156                            case OSG_UINT32_IMAGEDATA:
1157                                memcpy (data, getData(), destSize);
1158                                break;
1159                            case OSG_FLOAT32_IMAGEDATA:
1160                                memcpy (data, getData(), destSize);
1161                                break;
1162                            case OSG_FLOAT16_IMAGEDATA:
1163                                memcpy (data, getData(), destSize);
1164                                break;
1165
1166                            default:
1167                                FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1168                                break;
1169                            }
1170                            break;
1171
1172                        case OSG_LA_PF:
1173                            switch (getDataType())
1174                            {
1175                            case OSG_UINT8_IMAGEDATA:
1176                                for (srcI = destI = 0; destI < destSize;)
1177                                {
1178                                    data[destI++] = sourceData[srcI];
1179                                    data[destI++] = sourceData[srcI++];
1180                                }
1181                                break;
1182                            case OSG_UINT16_IMAGEDATA:
1183                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1184                                {
1185                                    destDataUC16[destI++] = sourceDataUC16[srcI];
1186                                    destDataUC16[destI++] = sourceDataUC16[srcI++];
1187                                }
1188                                break;
1189                            case OSG_UINT32_IMAGEDATA:
1190                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1191                                {
1192                                    destDataUC32[destI++] = sourceDataUC32[srcI];
1193                                    destDataUC32[destI++] = sourceDataUC32[srcI++];
1194                                }
1195                                break;
1196                            case OSG_FLOAT32_IMAGEDATA:
1197                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1198                                {
1199                                    destDataF32[destI++] = sourceDataF32[srcI];
1200                                    destDataF32[destI++] = sourceDataF32[srcI++];
1201                                }
1202                                break;
1203
1204                            case OSG_FLOAT16_IMAGEDATA:
1205                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1206                                {
1207                                    destDataH16[destI++] = sourceDataH16[srcI];
1208                                    destDataH16[destI++] = sourceDataH16[srcI++];
1209                                }
1210                                break;
1211                            default:
1212                                FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1213                                break;
1214                            }
1215                            break;
1216
1217                        case OSG_RGB_PF:
1218                            switch (getDataType())
1219                            {
1220                            case OSG_UINT8_IMAGEDATA:
1221                                for (srcI = destI = 0; destI < destSize;)
1222                                {
1223                                    data[destI++] = sourceData[srcI];
1224                                    data[destI++] = sourceData[srcI];
1225                                    data[destI++] = sourceData[srcI++];
1226                                }
1227                                break;
1228                            case OSG_UINT16_IMAGEDATA:
1229                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1230                                {
1231                                    destDataUC16[destI++] = sourceDataUC16[srcI];
1232                                    destDataUC16[destI++] = sourceDataUC16[srcI];
1233                                    destDataUC16[destI++] = sourceDataUC16[srcI++];
1234                                }
1235                                break;
1236                            case OSG_UINT32_IMAGEDATA:
1237                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1238                                {
1239                                    destDataUC32[destI++] = sourceDataUC32[srcI];
1240                                    destDataUC32[destI++] = sourceDataUC32[srcI];
1241                                    destDataUC32[destI++] = sourceDataUC32[srcI++];
1242                                }
1243                                break;
1244                            case OSG_FLOAT32_IMAGEDATA:
1245                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1246                                {
1247                                    destDataF32[destI++] = sourceDataF32[srcI];
1248                                    destDataF32[destI++] = sourceDataF32[srcI];
1249                                    destDataF32[destI++] = sourceDataF32[srcI++];
1250                                }
1251                                break;
1252                            case OSG_FLOAT16_IMAGEDATA:
1253                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1254                                {
1255                                    destDataH16[destI++] = sourceDataH16[srcI];
1256                                    destDataH16[destI++] = sourceDataH16[srcI];
1257                                    destDataH16[destI++] = sourceDataH16[srcI++];
1258                                }
1259                                break;
1260                            default:
1261                                FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1262                                break;
1263                            }
1264                            break;
1265
1266                        case OSG_RGBA_PF:
1267                            switch (getDataType())
1268                            {
1269                            case OSG_UINT8_IMAGEDATA:
1270                                for (srcI = destI = 0; destI < destSize;)
1271                                {
1272                                    data[destI++] = sourceData[srcI];
1273                                    data[destI++] = sourceData[srcI];
1274                                    data[destI++] = sourceData[srcI];
1275                                    data[destI++] = sourceData[srcI++];
1276                                }
1277                                break;
1278                            case OSG_UINT16_IMAGEDATA:
1279                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1280                                {
1281                                    destDataUC16[destI++] = sourceDataUC16[srcI];
1282                                    destDataUC16[destI++] = sourceDataUC16[srcI];
1283                                    destDataUC16[destI++] = sourceDataUC16[srcI];
1284                                    destDataUC16[destI++] = sourceDataUC16[srcI++];
1285                                }
1286                                break;
1287                            case OSG_UINT32_IMAGEDATA:
1288                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1289                                {
1290                                    destDataUC32[destI++] = sourceDataUC32[srcI];
1291                                    destDataUC32[destI++] = sourceDataUC32[srcI];
1292                                    destDataUC32[destI++] = sourceDataUC32[srcI];
1293                                    destDataUC32[destI++] = sourceDataUC32[srcI++];
1294                                }
1295                                break;
1296                            case OSG_FLOAT32_IMAGEDATA:
1297                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1298                                {
1299                                    destDataF32[destI++] = sourceDataF32[srcI];
1300                                    destDataF32[destI++] = sourceDataF32[srcI];
1301                                    destDataF32[destI++] = sourceDataF32[srcI];
1302                                    destDataF32[destI++] = sourceDataF32[srcI++];
1303                                }
1304                                break;
1305                            case OSG_FLOAT16_IMAGEDATA:
1306                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1307                                {
1308                                    destDataH16[destI++] = sourceDataH16[srcI];
1309                                    destDataH16[destI++] = sourceDataH16[srcI];
1310                                    destDataH16[destI++] = sourceDataH16[srcI];
1311                                    destDataH16[destI++] = sourceDataH16[srcI++];
1312                                }
1313                                break;
1314                            default:
1315                                FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1316                                break;
1317                            }
1318                            break;
1319                    default:
1320                        FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1321                        break;
1322                    }
1323                    break;
1324
1325                //-----------------------------------------------------
1326                case OSG_LA_PF:
1327                    switch (pixelFormat) 
1328                    {
1329                        case OSG_A_PF:
1330                            switch (getDataType())
1331                            {
1332                            case OSG_UINT8_IMAGEDATA:
1333                                for (srcI = destI = 0; destI < destSize;)
1334                                {
1335                                    srcI++;
1336                                    data[destI++] = sourceData[srcI++];
1337                                }
1338                                break;
1339                            case OSG_UINT16_IMAGEDATA:
1340                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1341                                {
1342                                    srcI++;
1343                                    destDataUC16[destI++] = sourceDataUC16[srcI++];
1344                                }
1345                                break;
1346                            case OSG_UINT32_IMAGEDATA:
1347                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1348                                {
1349                                    srcI++;
1350                                    destDataUC32[destI++] = sourceDataUC32[srcI++];
1351                                }
1352                                break;
1353                            case OSG_FLOAT32_IMAGEDATA:
1354                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1355                                {
1356                                    srcI++;
1357                                    destDataF32[destI++] = sourceDataF32[srcI++];
1358                                }
1359                                break;
1360                            case OSG_FLOAT16_IMAGEDATA:
1361                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1362                                {
1363                                    srcI++;
1364                                    destDataH16[destI++] = sourceDataH16[srcI++];
1365                                }
1366                                break;
1367                            default:
1368                                FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1369                                break;
1370                            }
1371                            break;
1372                        case OSG_I_PF:
1373                        case OSG_L_PF:
1374                            switch (getDataType())
1375                            {
1376                            case OSG_UINT8_IMAGEDATA:
1377                                for (srcI = destI = 0; destI < destSize;)
1378                                {
1379                                    data[destI++] = sourceData[srcI++];
1380                                    srcI++;
1381                                }
1382                                break;
1383                            case OSG_UINT16_IMAGEDATA:
1384                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1385                                {
1386                                    destDataUC16[destI++] = sourceDataUC16[srcI++];
1387                                    srcI++;
1388                                }
1389                                break;
1390                            case OSG_UINT32_IMAGEDATA:
1391                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1392                                {
1393                                    destDataUC32[destI++] = sourceDataUC32[srcI++];
1394                                    srcI++;
1395                                }
1396                                break;
1397                            case OSG_FLOAT32_IMAGEDATA:
1398                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1399                                {
1400                                    destDataF32[destI++] = sourceDataF32[srcI++];
1401                                    srcI++;
1402                                }
1403                                break;
1404                            case OSG_FLOAT16_IMAGEDATA:
1405                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1406                                {
1407                                    destDataH16[destI++] = sourceDataH16[srcI++];
1408                                    srcI++;
1409                                }
1410                                break;
1411                            default:
1412                                FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1413                                break;
1414                            }
1415                            break;
1416                        case OSG_LA_PF:
1417                            switch (getDataType())
1418                            {
1419                            case OSG_UINT8_IMAGEDATA:
1420                                memcpy (data, getData(), destSize);
1421                                break;
1422                            case OSG_UINT16_IMAGEDATA:
1423                                memcpy (data, getData(), destSize);
1424                                break;
1425                            case OSG_UINT32_IMAGEDATA:
1426                                memcpy (data, getData(), destSize);
1427                                break;
1428                            case OSG_FLOAT32_IMAGEDATA:
1429                                memcpy (data, getData(), destSize);
1430                                break;
1431                            case OSG_FLOAT16_IMAGEDATA:
1432                                memcpy (data, getData(), destSize);
1433                                break;
1434                            default:
1435                                FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1436                                break;
1437                            }
1438                            break;
1439
1440                        case OSG_RGB_PF:
1441                            switch (getDataType())
1442                            {
1443                            case OSG_UINT8_IMAGEDATA:
1444                                for (srcI = destI = 0; destI < destSize;)
1445                                {
1446                                    data[destI++] = sourceData[srcI];
1447                                    data[destI++] = sourceData[srcI];
1448                                    data[destI++] = sourceData[srcI++];
1449                                    srcI++;
1450                                }
1451                                break;
1452                            case OSG_UINT16_IMAGEDATA:
1453                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1454                                {
1455                                    destDataUC16[destI++] = sourceDataUC16[srcI];
1456                                    destDataUC16[destI++] = sourceDataUC16[srcI];
1457                                    destDataUC16[destI++] = sourceDataUC16[srcI++];
1458                                    srcI++;
1459                                }
1460                                break;
1461                            case OSG_UINT32_IMAGEDATA:
1462                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1463                                {
1464                                    destDataUC32[destI++] = sourceDataUC32[srcI];
1465                                    destDataUC32[destI++] = sourceDataUC32[srcI];
1466                                    destDataUC32[destI++] = sourceDataUC32[srcI++];
1467                                    srcI++;
1468                                }
1469                                break;
1470                            case OSG_FLOAT32_IMAGEDATA:
1471                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1472                                {
1473                                    destDataF32[destI++] = sourceDataF32[srcI];
1474                                    destDataF32[destI++] = sourceDataF32[srcI];
1475                                    destDataF32[destI++] = sourceDataF32[srcI++];
1476                                    srcI++;
1477                                }
1478                                break;
1479                            case OSG_FLOAT16_IMAGEDATA:
1480                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1481                                {
1482                                    destDataH16[destI++] = sourceDataH16[srcI];
1483                                    destDataH16[destI++] = sourceDataH16[srcI];
1484                                    destDataH16[destI++] = sourceDataH16[srcI++];
1485                                    srcI++;
1486                                }
1487                                break;
1488                            default:
1489                                FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1490                                break;
1491                            }
1492                            break;
1493
1494                        case OSG_RGBA_PF:
1495                            switch (getDataType())
1496                            {
1497                            case OSG_UINT8_IMAGEDATA:
1498                                for (srcI = destI = 0; destI < destSize;)
1499                                {
1500                                    data[destI++] = sourceData[srcI];
1501                                    data[destI++] = sourceData[srcI];
1502                                    data[destI++] = sourceData[srcI++];
1503                                    data[destI++] = sourceData[srcI++];
1504                                }
1505                                break;
1506                            case OSG_UINT16_IMAGEDATA:
1507                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1508                                {
1509                                    destDataUC16[destI++] = sourceDataUC16[srcI];
1510                                    destDataUC16[destI++] = sourceDataUC16[srcI];
1511                                    destDataUC16[destI++] = sourceDataUC16[srcI++];
1512                                    destDataUC16[destI++] = sourceDataUC16[srcI++];
1513                                }
1514                                break;
1515                            case OSG_UINT32_IMAGEDATA:
1516                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1517                                {
1518                                    destDataUC32[destI++] = sourceDataUC32[srcI];
1519                                    destDataUC32[destI++] = sourceDataUC32[srcI];
1520                                    destDataUC32[destI++] = sourceDataUC32[srcI++];
1521                                    destDataUC32[destI++] = sourceDataUC32[srcI++];
1522                                }
1523                                break;
1524                            case OSG_FLOAT32_IMAGEDATA:
1525                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1526                                {
1527                                    destDataF32[destI++] = sourceDataF32[srcI];
1528                                    destDataF32[destI++] = sourceDataF32[srcI];
1529                                    destDataF32[destI++] = sourceDataF32[srcI++];
1530                                    destDataF32[destI++] = sourceDataF32[srcI++];
1531                                }
1532                                break;
1533                            case OSG_FLOAT16_IMAGEDATA:
1534                                for (srcI = destI = 0; destI < destSize/getComponentSize();)
1535                                {
1536                                    destDataH16[destI++] = sourceDataH16[srcI];
1537                                    destDataH16[destI++] = sourceDataH16[srcI];
1538                                    destDataH16[destI++] = sourceDataH16[srcI++];
1539                                    destDataH16[destI++] = sourceDataH16[srcI++];
1540                                }
1541                                break;
1542                            default:
1543                                FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1544                                break;
1545                            }
1546                            break;
1547                    default:
1548                        FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1549                        break;
1550                    }
1551                    break;
1552
1553                //-----------------------------------------------------
1554                case OSG_RGB_PF:
1555                    switch (pixelFormat) 
1556                    {
1557                        case OSG_A_PF:
1558                        case OSG_I_PF:
1559                        case OSG_L_PF:
1560                            switch (getDataType())
1561                            {
1562                                case OSG_UINT8_IMAGEDATA:
1563                                    for (srcI = destI = 0; destI < destSize;)
1564                                    {
1565                                        sum = 0;
1566                                        sum += sourceData[srcI++];
1567                                        sum += sourceData[srcI++];
1568                                        sum += sourceData[srcI++];
1569                                        data[destI++] = sum / 3;
1570                                    }
1571                                    break;
1572                                case OSG_UINT16_IMAGEDATA:
1573                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1574                                    {
1575                                        sum = 0;
1576                                        sum += sourceDataUC16[srcI++];
1577                                        sum += sourceDataUC16[srcI++];
1578                                        sum += sourceDataUC16[srcI++];
1579                                        destDataUC16[destI++] = sum / 3;
1580                                    }
1581                                    break;
1582                                case OSG_UINT32_IMAGEDATA:
1583                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1584                                    {
1585                                        sum = 0;
1586                                        sum += sourceDataUC32[srcI++];
1587                                        sum += sourceDataUC32[srcI++];
1588                                        sum += sourceDataUC32[srcI++];
1589                                        destDataUC32[destI++] = sum / 3;
1590                                    }
1591                                    break;
1592                                case OSG_FLOAT32_IMAGEDATA:
1593                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1594                                    {
1595                                        sumReal = 0;
1596                                        sumReal += sourceDataF32[srcI++];
1597                                        sumReal += sourceDataF32[srcI++];
1598                                        sumReal += sourceDataF32[srcI++];
1599                                        destDataF32[destI++] = sumReal / 3.0;
1600                                    }
1601                                    break;
1602                                case OSG_FLOAT16_IMAGEDATA:
1603                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1604                                    {
1605                                        sumReal = 0;
1606                                        sumReal += sourceDataH16[srcI++];
1607                                        sumReal += sourceDataH16[srcI++];
1608                                        sumReal += sourceDataH16[srcI++];
1609                                        destDataH16[destI++] = sumReal / 3.0;
1610                                    }
1611                                    break;
1612                                default:
1613                                    FWARNING (( "RGB: Invalid source IMAGE_DATA_TYPE\n" ));
1614                                    break;
1615                            }
1616                            break;
1617                        case OSG_LA_PF:
1618                            switch (getDataType())
1619                            {
1620                                case OSG_UINT8_IMAGEDATA:
1621                                    for (srcI = destI = 0; destI < destSize;)
1622                                    {
1623                                        sum = 0;
1624                                        sum += sourceData[srcI++];
1625                                        sum += sourceData[srcI++];
1626                                        sum += sourceData[srcI++];
1627                                        data[destI++] = sum / 3;
1628                                        data[destI++] = sum / 3;
1629                                    }
1630                                    break;
1631                                case OSG_UINT16_IMAGEDATA:
1632                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1633                                    {
1634                                        sum = 0;
1635                                        sum += sourceDataUC16[srcI++];
1636                                        sum += sourceDataUC16[srcI++];
1637                                        sum += sourceDataUC16[srcI++];
1638                                        destDataUC16[destI++] = sum / 3;
1639                                        destDataUC16[destI++] = sum / 3;
1640                                    }
1641                                    break;
1642                                case OSG_UINT32_IMAGEDATA:
1643                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1644                                    {
1645                                        sum = 0;
1646                                        sum += sourceDataUC32[srcI++];
1647                                        sum += sourceDataUC32[srcI++];
1648                                        sum += sourceDataUC32[srcI++];
1649                                        destDataUC32[destI++] = sum / 3;
1650                                        destDataUC32[destI++] = sum / 3;
1651                                    }
1652                                    break;
1653                                case OSG_FLOAT32_IMAGEDATA:
1654                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1655                                    {
1656                                        sumReal = 0;
1657                                        sumReal += sourceDataF32[srcI++];
1658                                        sumReal += sourceDataF32[srcI++];
1659                                        sumReal += sourceDataF32[srcI++];
1660                                        destDataF32[destI++] = sumReal / 3.0;
1661                                        destDataF32[destI++] = sumReal / 3.0;
1662                                    }
1663                                    break;
1664                                case OSG_FLOAT16_IMAGEDATA:
1665                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1666                                    {
1667                                        sumReal = 0;
1668                                        sumReal += sourceDataH16[srcI++];
1669                                        sumReal += sourceDataH16[srcI++];
1670                                        sumReal += sourceDataH16[srcI++];
1671                                        destDataH16[destI++] = sumReal / 3.0;
1672                                        destDataH16[destI++] = sumReal / 3.0;
1673                                    }
1674                                    break;
1675                                default:
1676                                    FWARNING (( "RGB: Invalid source IMAGE_DATA_TYPE\n" ));
1677                                    break;
1678                            }
1679                            break;
1680                        case OSG_RGB_PF:
1681                            switch (getDataType())
1682                            {
1683                                case OSG_UINT8_IMAGEDATA:
1684                                    memcpy (data, getData(), destSize);
1685                                    break;
1686                                case OSG_UINT16_IMAGEDATA:
1687                                    memcpy (data, getData(), destSize);
1688                                    break;
1689                                case OSG_UINT32_IMAGEDATA:
1690                                    memcpy (data, getData(), destSize);
1691                                    break;
1692                                case OSG_FLOAT32_IMAGEDATA:
1693                                    memcpy (data, getData(), destSize);
1694                                    break;
1695                                case OSG_FLOAT16_IMAGEDATA:
1696                                    memcpy (data, getData(), destSize);
1697                                    break;
1698                                default:
1699                                    FWARNING (( "RGB: Invalid source IMAGE_DATA_TYPE\n" ));
1700                                break;
1701                            }
1702                            break;
1703
1704                        case OSG_RGBA_PF:
1705                            switch (getDataType())
1706                            {
1707                                case OSG_UINT8_IMAGEDATA:
1708                                    for (srcI = destI = 0; destI < destSize;)
1709                                    {
1710                                        sum = 0;
1711                                        sum += data[destI++] = sourceData[srcI++];
1712                                        sum += data[destI++] = sourceData[srcI++];
1713                                        sum += data[destI++] = sourceData[srcI++];
1714                                        data[destI++] = sum / 3;
1715                                    }
1716                                    break;
1717                                case OSG_UINT16_IMAGEDATA:
1718                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1719                                    {
1720                                        sum = 0;
1721                                        sum += destDataUC16[destI++] = sourceDataUC16[srcI++];
1722                                        sum += destDataUC16[destI++] = sourceDataUC16[srcI++];
1723                                        sum += destDataUC16[destI++] = sourceDataUC16[srcI++];
1724                                        destDataUC16[destI++] = sum / 3;
1725                                    }
1726                                    break;
1727                                case OSG_UINT32_IMAGEDATA:
1728                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1729                                    {
1730                                        sum = 0;
1731                                        sum += destDataUC32[destI++] = sourceDataUC32[srcI++];
1732                                        sum += destDataUC32[destI++] = sourceDataUC32[srcI++];
1733                                        sum += destDataUC32[destI++] = sourceDataUC32[srcI++];
1734                                        destDataUC32[destI++] = sum / 3;
1735                                    }
1736                                    break;
1737                                case OSG_FLOAT32_IMAGEDATA:
1738                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1739                                    {
1740                                        sumReal = 0;
1741                                        sumReal += destDataF32[destI++] = sourceDataF32[srcI++];
1742                                        sumReal += destDataF32[destI++] = sourceDataF32[srcI++];
1743                                        sumReal += destDataF32[destI++] = sourceDataF32[srcI++];
1744                                        destDataF32[destI++] = sumReal / 3.0;
1745                                    }
1746                                    break;
1747                                case OSG_FLOAT16_IMAGEDATA:
1748                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1749                                    {
1750                                        sumReal = 0;
1751                                        sumReal += destDataH16[destI++] = sourceDataH16[srcI++];
1752                                        sumReal += destDataH16[destI++] = sourceDataH16[srcI++];
1753                                        sumReal += destDataH16[destI++] = sourceDataH16[srcI++];
1754                                        destDataH16[destI++] = sumReal / 3.0;
1755                                    }
1756                                    break;
1757                                default:
1758                                    FWARNING (( "RGB: Invalid source IMAGE_DATA_TYPE\n" ));
1759                                    break;
1760                            }
1761                            break;
1762#if defined(GL_COMPRESSED_RGB_S3TC_DXT1_EXT)
1763                        case OSG_RGB_DXT1:
1764                        {
1765                            iCompressionFlags |= osgsquish::kDxt1;
1766
1767#ifdef OSG_DEBUG
1768                            Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(), 
1769                                                                               getHeight(), 
1770                                                                               iCompressionFlags);
1771
1772                            OSG_ASSERT(iStorage == destSize);
1773#endif
1774
1775                            osgsquish::CompressImage(sourceData, 
1776                                                     255, 
1777                                                     getWidth (), 
1778                                                     getHeight(),
1779                                                     data,
1780                                                     iCompressionFlags);
1781                        }
1782                        break;
1783#endif
1784#if defined(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
1785                        case OSG_RGBA_DXT1:
1786                        {
1787                            iCompressionFlags |= osgsquish::kDxt1;
1788
1789#ifdef OSG_DEBUG
1790                            Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(), 
1791                                                                               getHeight(), 
1792                                                                               iCompressionFlags);
1793
1794                            OSG_ASSERT(iStorage == destSize);
1795#endif
1796
1797                            osgsquish::CompressImage(sourceData, 
1798                                                     255, 
1799                                                     getWidth (), 
1800                                                     getHeight(),
1801                                                     data,
1802                                                     iCompressionFlags);
1803                        }
1804                        break;
1805#endif
1806#if defined(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)
1807                        case OSG_RGBA_DXT3:
1808                        {
1809                            iCompressionFlags |= osgsquish::kDxt3; 
1810
1811#ifdef OSG_DEBUG
1812                            Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(), 
1813                                                                               getHeight(), 
1814                                                                               iCompressionFlags);
1815
1816                            OSG_ASSERT(iStorage == destSize);
1817#endif
1818
1819                            osgsquish::CompressImage(sourceData, 
1820                                                     255, 
1821                                                     getWidth (), 
1822                                                     getHeight(),
1823                                                     data,
1824                                                     iCompressionFlags);
1825                        }
1826                        break;
1827#endif
1828#if defined(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
1829                        case OSG_RGBA_DXT5:
1830                        {
1831                            iCompressionFlags |= osgsquish::kDxt5;
1832
1833#ifdef OSG_DEBUG
1834                            Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(), 
1835                                                                               getHeight(), 
1836                                                                               iCompressionFlags);
1837
1838                            OSG_ASSERT(iStorage == destSize);
1839#endif
1840
1841                            osgsquish::CompressImage(sourceData, 
1842                                                     255, 
1843                                                     getWidth (), 
1844                                                     getHeight(),
1845                                                     data,
1846                                                     iCompressionFlags);
1847                        }
1848                        break;
1849#endif
1850
1851                        default:
1852                            FWARNING (( "RGB: Invalid target IMAGE_DATA_TYPE\n" ));
1853                            break;
1854                    }
1855                    break;
1856
1857
1858                    //-----------------------------------------------------
1859                case OSG_RGBA_PF:
1860                {
1861                    switch (pixelFormat) 
1862                    {
1863                        case OSG_A_PF:
1864                            switch (getDataType())
1865                            {
1866                                case OSG_UINT8_IMAGEDATA:
1867                                    for (srcI = destI = 0; destI < destSize;)
1868                                    {
1869                                        srcI += 3;
1870                                        data[destI++] = sourceData[srcI++];;
1871                                    }
1872                                    break;
1873                                case OSG_UINT16_IMAGEDATA:
1874                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1875                                    {
1876                                        srcI += 3;
1877                                        destDataUC16[destI++] = sourceDataUC16[srcI++];;
1878                                    }
1879                                    break;
1880                                case OSG_UINT32_IMAGEDATA:
1881                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1882                                    {
1883                                        srcI += 3;
1884                                        destDataUC32[destI++] = sourceDataUC32[srcI++];;
1885                                    }
1886                                    break;
1887                                case OSG_FLOAT32_IMAGEDATA:
1888                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1889                                    {
1890                                        srcI += 3;
1891                                        destDataF32[destI++] = sourceDataF32[srcI++];
1892                                    }
1893                                    break;
1894                                case OSG_FLOAT16_IMAGEDATA:
1895                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1896                                    {
1897                                        srcI += 3;
1898                                        destDataH16[destI++] = sourceDataH16[srcI++];
1899                                    }
1900                                    break;
1901                                default:
1902                                    FWARNING (( "RGBA: Invalid source IMAGE_DATA_TYPE\n" ));
1903                                    break;
1904                            }
1905                            break;
1906
1907                        case OSG_I_PF:
1908                        case OSG_L_PF:
1909                            switch (getDataType())
1910                            {
1911                                case OSG_UINT8_IMAGEDATA:
1912                                    for (srcI = destI = 0; destI < destSize;)
1913                                    {
1914                                        sum = 0;
1915                                        sum += sourceData[srcI++];
1916                                        sum += sourceData[srcI++];
1917                                        sum += sourceData[srcI++];
1918                                        data[destI++] = sum / 3;
1919                                        srcI++;
1920                                    }
1921                                    break;
1922                                case OSG_UINT16_IMAGEDATA:
1923                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1924                                    {
1925                                        sum = 0;
1926                                        sum += sourceDataUC16[srcI++];
1927                                        sum += sourceDataUC16[srcI++];
1928                                        sum += sourceDataUC16[srcI++];
1929                                        destDataUC16[destI++] = sum / 3;
1930                                        srcI++;
1931                                    }
1932                                    break;
1933                                case OSG_UINT32_IMAGEDATA:
1934                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1935                                    {
1936                                        sum = 0;
1937                                        sum += sourceDataUC32[srcI++];
1938                                        sum += sourceDataUC32[srcI++];
1939                                        sum += sourceDataUC32[srcI++];
1940                                        destDataUC32[destI++] = sum / 3;
1941                                        srcI++;
1942                                    }
1943                                    break;
1944                                case OSG_FLOAT32_IMAGEDATA:
1945                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1946                                    {
1947                                        sumReal = 0;
1948                                        sumReal += sourceDataF32[srcI++];
1949                                        sumReal += sourceDataF32[srcI++];
1950                                        sumReal += sourceDataF32[srcI++];
1951                                        destDataF32[destI++] = sumReal / 3.0;
1952                                        srcI++;
1953                                    }
1954                                    break;
1955                                case OSG_FLOAT16_IMAGEDATA:
1956                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1957                                    {
1958                                        sumReal = 0;
1959                                        sumReal += sourceDataH16[srcI++];
1960                                        sumReal += sourceDataH16[srcI++];
1961                                        sumReal += sourceDataH16[srcI++];
1962                                        destDataH16[destI++] = sumReal / 3.0;
1963                                        srcI++;
1964                                    }
1965                                    break;
1966                                default:
1967                                    FWARNING (( "RGBA: Invalid source IMAGE_DATA_TYPE\n" ));
1968                                    break;
1969                            }
1970                            break;
1971
1972                        case OSG_LA_PF:
1973                            switch (getDataType())
1974                            {
1975                                case OSG_UINT8_IMAGEDATA:
1976                                    for (srcI = destI = 0; destI < destSize;)
1977                                    {
1978                                        sum = 0;
1979                                        sum += sourceData[srcI++];
1980                                        sum += sourceData[srcI++];
1981                                        sum += sourceData[srcI++];
1982                                        data[destI++] = sum / 3;
1983                                        data[destI++] = sourceData[srcI++];;
1984                                    }
1985                                    break;
1986                                case OSG_UINT16_IMAGEDATA:
1987                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1988                                    {
1989                                        sum = 0;
1990                                        sum += sourceDataUC16[srcI++];
1991                                        sum += sourceDataUC16[srcI++];
1992                                        sum += sourceDataUC16[srcI++];
1993                                        destDataUC16[destI++] = sum / 3;
1994                                        destDataUC16[destI++] = sourceDataUC16[srcI++];;
1995                                    }
1996                                    break;
1997                                case OSG_UINT32_IMAGEDATA:
1998                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
1999                                    {
2000                                        sum = 0;
2001                                        sum += sourceDataUC32[srcI++];
2002                                        sum += sourceDataUC32[srcI++];
2003                                        sum += sourceDataUC32[srcI++];
2004                                        destDataUC32[destI++] = sum / 3;
2005                                        destDataUC32[destI++] = sourceDataUC32[srcI++];;
2006                                    }
2007                                    break;
2008                                case OSG_FLOAT32_IMAGEDATA:
2009                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
2010                                    {
2011                                        sumReal = 0;
2012                                        sumReal += sourceDataF32[srcI++];
2013                                        sumReal += sourceDataF32[srcI++];
2014                                        sumReal += sourceDataF32[srcI++];
2015                                        destDataF32[destI++] = sumReal / 3.0;
2016                                        destDataF32[destI++] = sourceDataF32[srcI++];
2017                                    }
2018                                    break;
2019                                case OSG_FLOAT16_IMAGEDATA:
2020                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
2021                                    {
2022                                        sumReal = 0;
2023                                        sumReal += sourceDataH16[srcI++];
2024                                        sumReal += sourceDataH16[srcI++];
2025                                        sumReal += sourceDataH16[srcI++];
2026                                        destDataH16[destI++] = sumReal / 3.0;
2027                                        destDataH16[destI++] = sourceDataH16[srcI++];
2028                                    }
2029                                    break;
2030                                default:
2031                                    FWARNING (( "RGBA: Invalid source IMAGE_DATA_TYPE\n" ));
2032                                    break;
2033                            }
2034                            break;
2035
2036                        case OSG_RGB_PF:
2037                            switch (getDataType())
2038                            {
2039                                case OSG_UINT8_IMAGEDATA:
2040                                    for (srcI = destI = 0; destI < destSize;)
2041                                    {
2042                                        data[destI++] = sourceData[srcI++];
2043                                        data[destI++] = sourceData[srcI++];
2044                                        data[destI++] = sourceData[srcI++];
2045                                        srcI++;
2046                                    }
2047                                    break;
2048                                case OSG_UINT16_IMAGEDATA:
2049                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
2050                                    {
2051                                        destDataUC16[destI++] = sourceDataUC16[srcI++];
2052                                        destDataUC16[destI++] = sourceDataUC16[srcI++];
2053                                        destDataUC16[destI++] = sourceDataUC16[srcI++];
2054                                        srcI++;
2055                                    }
2056                                    break;
2057                                case OSG_UINT32_IMAGEDATA:
2058                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
2059                                    {
2060                                        destDataUC32[destI++] = sourceDataUC32[srcI++];
2061                                        destDataUC32[destI++] = sourceDataUC32[srcI++];
2062                                        destDataUC32[destI++] = sourceDataUC32[srcI++];
2063                                        srcI++;
2064                                    }
2065                                    break;
2066                                case OSG_FLOAT32_IMAGEDATA:
2067                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
2068                                    {
2069                                        destDataF32[destI++] = sourceDataF32[srcI++];
2070                                        destDataF32[destI++] = sourceDataF32[srcI++];
2071                                        destDataF32[destI++] = sourceDataF32[srcI++];
2072                                        srcI++;
2073                                    }
2074                                    break;
2075                                case OSG_FLOAT16_IMAGEDATA:
2076                                    for (srcI = destI = 0; destI < destSize/getComponentSize();)
2077                                    {
2078                                        destDataH16[destI++] = sourceDataH16[srcI++];
2079                                        destDataH16[destI++] = sourceDataH16[srcI++];
2080                                        destDataH16[destI++] = sourceDataH16[srcI++];
2081                                        srcI++;
2082                                    }
2083                                    break;
2084                                default:
2085                                    FWARNING (( "RGBA: Invalid source IMAGE_DATA_TYPE\n" ));
2086                                    break;
2087                            }
2088                            break;
2089
2090                        case OSG_RGBA_PF:
2091                            switch (getDataType())
2092                            {
2093                                case OSG_UINT8_IMAGEDATA:
2094                                    memcpy (data, getData(), destSize);
2095                                    break;
2096                                case OSG_UINT16_IMAGEDATA:
2097                                    memcpy (data, getData(), destSize);
2098                                    break;
2099                                case OSG_UINT32_IMAGEDATA:
2100                                    memcpy (data, getData(), destSize);
2101                                    break;
2102                                case OSG_FLOAT32_IMAGEDATA:
2103                                    memcpy (data, getData(), destSize);
2104                                    break;
2105                                case OSG_FLOAT16_IMAGEDATA:
2106                                    memcpy (data, getData(), destSize);
2107                                    break;
2108                                default:
2109                                    FWARNING (( "RGBA: Invalid source IMAGE_DATA_TYPE\n" ));
2110                                    break;
2111                            }
2112                            break;
2113
2114#if defined(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
2115                        case OSG_RGBA_DXT1:
2116                        {
2117                            iCompressionFlags |= osgsquish::kDxt1;
2118
2119#ifdef OSG_DEBUG
2120                            Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(), 
2121                                                                               getHeight(), 
2122                                                                               iCompressionFlags);
2123
2124                            OSG_ASSERT(iStorage == destSize);
2125#endif
2126
2127                            osgsquish::CompressImage(sourceData, 
2128                                                     getWidth (), 
2129                                                     getHeight(),
2130                                                     data,
2131                                                     iCompressionFlags);
2132                        }
2133                        break;
2134#endif
2135#if defined(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)
2136                        case OSG_RGBA_DXT3:
2137                        {
2138                            iCompressionFlags |= osgsquish::kDxt3; 
2139
2140#ifdef OSG_DEBUG
2141                            Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(), 
2142                                                                               getHeight(), 
2143                                                                               iCompressionFlags);
2144
2145                            OSG_ASSERT(iStorage == destSize);
2146#endif
2147
2148                            osgsquish::CompressImage(sourceData, 
2149                                                     getWidth (), 
2150                                                     getHeight(),
2151                                                     data,
2152                                                     iCompressionFlags);
2153                        }
2154                        break;
2155#endif
2156#if defined(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
2157                        case OSG_RGBA_DXT5:
2158                        {
2159                            iCompressionFlags |= osgsquish::kDxt5;
2160
2161#ifdef OSG_DEBUG
2162                            Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(), 
2163                                                                               getHeight(), 
2164                                                                               iCompressionFlags);
2165
2166                            OSG_ASSERT(iStorage == destSize);
2167#endif
2168
2169                            osgsquish::CompressImage(sourceData, 
2170                                                     getWidth (), 
2171                                                     getHeight(),
2172                                                     data,
2173                                                     iCompressionFlags);
2174                        }
2175                        break;
2176#endif
2177
2178                        default:
2179                            break;
2180                    }
2181                    break;
2182                }
2183
2184				case OSG_ALPHA_INTEGER_PF:
2185				case OSG_RGB_INTEGER_PF:
2186				case OSG_RGBA_INTEGER_PF:
2187				case OSG_BGR_INTEGER_PF:
2188				case OSG_BGRA_INTEGER_PF:
2189				case OSG_LUMINANCE_INTEGER_PF:
2190				case OSG_LUMINANCE_ALPHA_INTEGER_PF:
2191                {
2192                    FFATAL((" 'reformat' NYI\n "));
2193                }
2194                break;
2195
2196                default:
2197                    FWARNING (( "Unvalid pixeldepth (%d) in reformat() !\n",
2198                                pixelFormat ));
2199            }
2200        }
2201        if (data)
2202        {
2203            // rip the data from the local destImage if necessary
2204            if(destination == NULL)
2205            {
2206                this->set(dest);
2207            }
2208        }
2209    }
2210
2211    return (data ? true : false);
2212}
2213
2214void Image::swapDataEndian(void)
2215{
2216    UChar8 *data     = editData();
2217
2218    UInt32  size     = getSize() / getComponentSize();
2219    UInt16 *dataUC16 = reinterpret_cast<UInt16 *>(data);
2220    UInt32 *dataUC32 = reinterpret_cast<UInt32 *>(data);
2221    Real32 *dataF32  = reinterpret_cast<Real32 *>(data);
2222
2223
2224    switch (getDataType())
2225    {
2226        case OSG_UINT8_IMAGEDATA:
2227            // do nothing
2228            break;
2229
2230        case OSG_UINT16_IMAGEDATA:
2231
2232            for(UInt32 i=0;i<size;++i)
2233            {
2234                UInt16 p = dataUC16[i];
2235
2236                dataUC16[i] = (((p >> 8)) | (p << 8));
2237            }
2238            break;
2239
2240        case OSG_UINT32_IMAGEDATA:
2241
2242            for(UInt32 i=0;i<size;++i)
2243            {
2244                UInt32 p = dataUC32[i];
2245
2246                dataUC32[i] =
2247                    (((p & 0x000000FF) << 24) | ((p & 0x0000FF00) <<  8) |
2248                     ((p & 0x00FF0000) >>  8) | ((p & 0xFF000000) >> 24) );
2249            }
2250
2251            break;
2252
2253        case OSG_FLOAT32_IMAGEDATA:
2254
2255            for(UInt32 i=0;i<size;++i)
2256            {
2257                Real32 p = dataF32[i];
2258                UInt8 *b = reinterpret_cast<UInt8 *>(&p);
2259
2260                std::swap(b[0], b[3]);
2261                std::swap(b[1], b[2]);
2262
2263                dataF32[i] = p;
2264            }
2265            break;
2266
2267		case OSG_INT16_IMAGEDATA:
2268		case OSG_INT32_IMAGEDATA:
2269        {
2270            FFATAL((" 'swapDataEndian' NYI\n "));
2271        }
2272		break;
2273
2274        default:
2275            FWARNING (( "invalid source data type \n"));
2276            break;
2277    }
2278}
2279
2280/*! It is a simple method to convert the image dataType. Does not change
2281  the pixelFormat. So you can for example convert a image consisting of
2282  UChar8 data to Float data.
2283 */
2284
2285bool Image::convertDataTypeTo(Int32 destDataType)
2286{
2287    if (hasCompressedData())
2288    {
2289        FFATAL (("Invalid Image::convertDataTypeTo for compressed image\n"));
2290        return false;
2291    }
2292
2293    if(destDataType == getDataType())
2294    {
2295        FWARNING (( "source image and destination image have same data "
2296                    "types: no conversion possible"));
2297        return true;
2298    }
2299
2300    FINFO(("Try to convert image from dataType %d to %d\n",
2301           getDataType(), destDataType));
2302
2303    ImageUnrecPtr dest;
2304
2305    dest = Image::create();
2306
2307    dest->set(getPixelFormat(),
2308              getWidth      (),
2309              getHeight     (),
2310              getDepth      (),
2311              getMipMapCount(),
2312              getFrameCount (),
2313              0.0,
2314              0,
2315              destDataType,
2316              true,
2317              getSideCount()  );
2318
2319    const UChar8 *sourceData = getData();
2320          UChar8 *destData   = dest->editData();
2321
2322    UInt32 sourceSize = getSize() / getComponentSize();
2323
2324    const UInt16 *sourceDataUC16 = reinterpret_cast<const UInt16 *>(sourceData);
2325          UInt16 *destDataUC16   = reinterpret_cast<      UInt16 *>(destData  );
2326    const UInt32 *sourceDataUC32 = reinterpret_cast<const UInt32 *>(sourceData);
2327          UInt32 *destDataUC32   = reinterpret_cast<      UInt32 *>(destData  );
2328    const Real32 *sourceDataF32  = reinterpret_cast<const Real32 *>(sourceData);
2329          Real32 *destDataF32    = reinterpret_cast<      Real32 *>(destData  );
2330//    const Real16 *sourceDataH16  = reinterpret_cast<const Real16 *>(sourceData);
2331          Real16 *destDataH16    = reinterpret_cast<      Real16 *>(destData  );
2332
2333    switch (getDataType())
2334    {
2335        case OSG_UINT8_IMAGEDATA:
2336
2337            switch (destDataType)
2338            {
2339                case OSG_UINT16_IMAGEDATA:
2340
2341                    for (UInt32 i = 0; i < sourceSize; i++)
2342                    {
2343                        destDataUC16[i] = UInt16(sourceData[i]<<8);
2344                    }
2345                    break;
2346
2347                case OSG_UINT32_IMAGEDATA:
2348
2349                    for (UInt32 i = 0; i < sourceSize; i++)
2350                    {
2351                        destDataUC32[i] = UInt32(sourceData[i]<<24);
2352                    }
2353                    break;
2354
2355                case OSG_FLOAT32_IMAGEDATA:
2356
2357                    for (UInt32 i = 0; i < sourceSize; i++)
2358                    {
2359                        destDataF32[i] = Real32(sourceData[i]/255.0);
2360                    }
2361                    break;
2362
2363                case OSG_FLOAT16_IMAGEDATA:
2364
2365                    for (UInt32 i = 0; i < sourceSize; i++)
2366                    {
2367                        destDataH16[i] = Real16(sourceData[i]/255.0);
2368                    }
2369                    break;
2370
2371                default:
2372                    FWARNING (( "invalid destination data type \n" ));
2373                    break;
2374            }
2375
2376            break;
2377
2378        case OSG_UINT16_IMAGEDATA:
2379
2380            switch (destDataType)
2381            {
2382                case OSG_UINT8_IMAGEDATA:
2383                {
2384                    UInt16 nMin = UInt16(65535);
2385                    UInt16 nMax = UInt16(0    );
2386
2387                    for (UInt32 i = 0; i < sourceSize; ++i)
2388                    {
2389                        if(sourceDataUC16[i] > nMax)
2390                            nMax = sourceDataUC16[i];
2391
2392                        if(sourceDataUC16[i] < nMin)
2393                            nMin = sourceDataUC16[i];
2394                    }
2395
2396                    Real32 fRange = Real32(nMax - nMin);
2397
2398                    if (fRange <= 0.0)
2399                    {
2400                        for(UInt32 i = 0; i < sourceSize; ++i)
2401                            destData[i] = 0;
2402                    }
2403                    else
2404                    {
2405                        for(UInt32 i = 0; i < sourceSize; ++i)
2406                        {
2407                            destData[i] = UInt8
2408                                (255.0 *
2409                                 (Real32 (sourceDataUC16[i] - nMin)) /
2410                                 fRange)                              ;
2411                        }
2412                    }
2413                }
2414                break;
2415
2416                case OSG_UINT32_IMAGEDATA:
2417
2418                    for (UInt32 i = 0; i < sourceSize; i++)
2419                    {
2420                        destDataUC32[i] = UInt32(sourceDataUC16[i]<<16);
2421                    }
2422                    break;
2423
2424                case OSG_FLOAT32_IMAGEDATA:
2425
2426                    for (UInt32 i = 0; i < sourceSize; i++)
2427                    {
2428                        destDataF32[i] = Real32(sourceDataUC16[i]/65535.0);
2429                    }
2430
2431                    break;
2432
2433                case OSG_FLOAT16_IMAGEDATA:
2434
2435                    for (UInt32 i = 0; i < sourceSize; i++)
2436                    {
2437                        destDataH16[i] = Real16(sourceDataUC16[i]/255.0);
2438                    }
2439                    break;
2440
2441                default:
2442                    FWARNING (( "invalid destination data type \n" ));
2443                    break;
2444            }
2445            break;
2446
2447        case OSG_UINT32_IMAGEDATA:
2448
2449            switch (destDataType)
2450            {
2451                case OSG_UINT8_IMAGEDATA:
2452                {
2453                    UInt32 nMin = UInt32(4294967295ul);
2454                    UInt32 nMax = UInt32(0           );
2455
2456                    for (UInt32 i = 0; i < sourceSize; ++i)
2457                    {
2458                        if(sourceDataUC32[i] > nMax)
2459                            nMax = sourceDataUC32[i];
2460
2461                        if(sourceDataUC32[i] < nMin)
2462                            nMin = sourceDataUC32[i];
2463                    }
2464
2465                    Real32 fRange = Real32(nMax - nMin);
2466
2467                    if (fRange <= 0.0)
2468                    {
2469                        for(UInt32 i = 0; i < sourceSize; ++i)
2470                            destData[i] = 0;
2471                    }
2472                    else
2473                    {
2474                        for(UInt32 i = 0; i < sourceSize; ++i)
2475                        {
2476                            destData[i] = UInt8
2477                                (255.0 *
2478                                 (Real32(sourceDataUC32[i] - nMin)) /
2479                                 fRange                             );
2480                        }
2481                    }
2482                }
2483                break;
2484
2485                case OSG_UINT16_IMAGEDATA:
2486                {
2487                    UInt32 nMin = UInt32(4294967295ul);
2488                    UInt32 nMax = UInt32(0           );
2489
2490                    for(UInt32 i = 0; i < sourceSize; ++i)
2491                    {
2492                        if(sourceDataUC32[i] > nMax)
2493                            nMax = sourceDataUC32[i];
2494
2495                        if(sourceDataUC32[i] < nMin)
2496                            nMin = sourceDataUC32[i];
2497                    }
2498
2499                    Real32 fRange = Real32(nMax - nMin);
2500
2501                    if(fRange <= 0.0)
2502                    {
2503                        for(UInt32 i = 0; i < sourceSize; ++i)
2504                            destDataUC16[i] = 0;
2505                    }
2506                    else
2507                    {
2508                        for(UInt32 i = 0; i < sourceSize; ++i)
2509                            destDataUC16[i] = UInt16
2510                                (65535.0 *
2511                                 (Real32(sourceDataUC32[i] - nMin)) /
2512                                 fRange);
2513                    }
2514                }
2515                break;
2516
2517                case OSG_FLOAT32_IMAGEDATA:
2518                    for(UInt32 i = 0; i < sourceSize; i++)
2519                    {
2520                        destDataF32[i] =
2521                            (Real32(sourceDataUC32[i])) / 4294967295.0;
2522                    }
2523                    break;
2524
2525                case OSG_FLOAT16_IMAGEDATA:
2526
2527                    for (UInt32 i = 0; i < sourceSize; i++)
2528                    {
2529                        destDataH16[i] =
2530                            (Real16(sourceDataUC32[i])) / REAL16_MAX;
2531                    }
2532                    break;
2533
2534                default:
2535                    FWARNING(("invalid destination data type \n"));
2536                    break;
2537            }
2538            break;
2539
2540        case OSG_FLOAT32_IMAGEDATA:
2541
2542            switch(destDataType)
2543            {
2544                case OSG_UINT8_IMAGEDATA:
2545
2546                    for(UInt32 i = 0; i < sourceSize; i++)
2547                    {
2548                        destData[i] = UInt8(sourceDataF32[i]*255.0);
2549                    }
2550                    break;
2551
2552                case OSG_UINT16_IMAGEDATA:
2553
2554                    for(UInt32 i = 0; i < sourceSize; i++)
2555                    {
2556                        destDataUC16[i] =
2557                            UInt16(sourceDataF32[i] * 65535.0);
2558                    }
2559                    break;
2560
2561                case OSG_UINT32_IMAGEDATA:
2562                    for(UInt32 i = 0; i < sourceSize; i++)
2563                    {
2564                        destDataUC32[i] =
2565                            UInt32(sourceDataF32[i] * 4294967295.0);
2566                    }
2567                    break;
2568
2569                case OSG_FLOAT16_IMAGEDATA:
2570
2571                    for (UInt32 i = 0; i < sourceSize; i++)
2572                    {
2573                        destDataH16[i] =
2574                            Real16(sourceDataF32[i]); // half-constructor
2575                    }
2576                    break;
2577
2578                default:
2579                    FWARNING(("invalid destination data type \n"));
2580                    break;
2581            }
2582            break;
2583
2584		case OSG_INT16_IMAGEDATA:
2585		case OSG_INT32_IMAGEDATA:
2586        {
2587            FFATAL((" 'convertDataTypeTo' NYI\n "));
2588        }
2589        break;
2590
2591        default:
2592            FWARNING (( "invalid source data type \n"));
2593            break;
2594    }
2595
2596    if(dest->getData() != NULL)
2597    {
2598        this->set(dest);
2599    }
2600
2601    return (getData() ? true : false);
2602}
2603
2604/*! It just fills the hole image data with the given pixel value. It is
2605    mainly used to initialize the image data.
2606 */
2607
2608void Image::clear(UChar8 pixelValue)
2609{
2610    if(getData() != NULL)
2611        memset(editData(), pixelValue, getSize());
2612}
2613
2614void Image::clearFloat(Real32 pixelValue)
2615{
2616    unsigned long  n = getSize()/getComponentSize();
2617    Real32        *d = reinterpret_cast<Real32 *>(editData());
2618
2619    if(n && d)
2620    {
2621        while(n--)
2622        {
2623            *d++ = pixelValue;
2624        }
2625    }
2626}
2627
2628void Image::clearHalf(Real16 pixelValue)
2629{
2630    unsigned long  n = getSize()/getComponentSize();
2631    Real16        *d = reinterpret_cast<Real16 *>(editData());
2632
2633    if(n && d)
2634        while(n--)
2635            *d++ = pixelValue;
2636}
2637
2638/*-------------------------------------------------------------------------*/
2639/*                             attachment handling                         */
2640
2641/*! returns true if the image has any attachments
2642 */
2643
2644bool Image::hasAttachment(void) const
2645{
2646    Image *img=const_cast<Image*>(this);
2647
2648    ImageGenericAtt *att = dynamic_cast<ImageGenericAtt *>(
2649        img->Inherited::findAttachment(
2650            ImageGenericAtt::getClassType().getGroupId()));
2651
2652    if(att != NULL && att->getType().getNumFieldDescs() > 1)
2653        return true;
2654    else
2655        return false;
2656}
2657
2658/*! returns the number of attachments
2659 */
2660
2661UInt32 Image::attachmentCount(void) const
2662{
2663    Image *img=const_cast<Image*>(this);
2664
2665    ImageGenericAtt *att = dynamic_cast<ImageGenericAtt *>(
2666        img->Inherited::findAttachment(
2667            ImageGenericAtt::getClassType().getGroupId()));
2668
2669    if(att != NULL)
2670    {
2671        return att->getType().getNumFieldDescs() -1;
2672    }
2673    else
2674    {
2675        return 0;
2676    }
2677}
2678
2679/*! set a single string attachment for the given key/data pair
2680 */
2681
2682void Image::setAttachmentField(const std::string &key,
2683                               const std::string &data)
2684{
2685    ImageGenericAttUnrecPtr att(dynamic_cast<ImageGenericAtt *>(
2686        findAttachment(
2687            ImageGenericAtt::getClassType().getGroupId())));
2688
2689
2690    if(att == NULL)
2691    {
2692        att = ImageGenericAtt::create();
2693
2694        addAttachment(att);
2695    }
2696
2697    if(att == NULL)
2698    {
2699        FWARNING(("Image::setAttachmentField - can not create attachment\n"));
2700
2701        return;
2702    }
2703
2704    EditFieldHandlePtr field = att->editDynamicFieldByName(key.c_str());
2705
2706    if(field == NULL)
2707    {
2708        SFString::Description pDesc = SFString::Description(
2709            SFString::getClassType(),
2710            key.c_str(),
2711            "",
2712            0,
2713            0,
2714            true,
2715            Field::SFDefaultFlags,
2716            static_cast<FieldIndexEditMethodSig>(
2717                &ImageGenericAtt::editDynamicField),
2718            static_cast<FieldIndexGetMethodSig >(
2719                &ImageGenericAtt::getDynamicField ));
2720
2721
2722        UInt32 fieldId = att->addField(pDesc);
2723
2724        field = att->editDynamicField(fieldId);
2725    }
2726
2727    SFString::EditHandlePtr strField = 
2728        boost::static_pointer_cast<SFString::EditHandle>(field);
2729
2730    if(strField != NULL && strField->isValid() == true)
2731        (*strField)->setValue(data);
2732}
2733
2734/*! returns the string attachment for the given key or Null
2735 */
2736
2737const std::string *Image::findAttachmentField(const std::string &key) const
2738{
2739    Image *img=const_cast<Image*>(this);
2740
2741    ImageGenericAtt *att = dynamic_cast<ImageGenericAtt *>(
2742        img->findAttachment(
2743            ImageGenericAtt::getClassType().getGroupId()));
2744
2745    if(att != NULL)
2746    {
2747        GetFieldHandlePtr field = att->getDynamicFieldByName(key.c_str());
2748
2749        if(field != NULL)
2750        {
2751            SFString::GetHandlePtr strField = 
2752                boost::static_pointer_cast<SFString::GetHandle>(field);
2753
2754            if(strField != NULL && strField->isValid() == true)
2755                return &((*strField)->getValue());
2756        }
2757    }
2758
2759    return NULL;
2760}
2761
2762/*! Method to scale the image. It just does a very simple but fast
2763  'nearest' scale. Should handle mipmap and frame data correct.
2764  The method can operate on the object or stores the result in
2765  the optional destination Image.
2766 */
2767
2768bool Image::scale(Int32  width,
2769                  Int32  height,
2770                  Int32  depth,
2771                  Image *destination)
2772{
2773    Image         *destImage;
2774    UInt32         sw, sh, sd, dw, dh, dd;
2775    Int32          frame, side, mipmap;
2776    const UChar8  *src;
2777    UChar8        *dest;
2778    Int32          oldWidth =getWidth();
2779    Int32          oldHeight=getHeight();
2780    Int32          oldDepth =getDepth();
2781
2782    if ( (oldWidth  == width ) &&
2783         (oldHeight == height) &&
2784         (oldDepth  == depth )   ) 
2785    {
2786        if(destination != NULL)
2787            *destination = *this;
2788        
2789        return true;
2790    }
2791    if (hasCompressedData())
2792    {
2793        FFATAL (("Invalid Image::scale for compressed image\n"));
2794        return false;
2795    }
2796
2797    if(destination != NULL)
2798    {
2799        destImage = destination;
2800    }
2801    else
2802    {
2803        destImage = this;
2804    }
2805
2806    // get pixel
2807    // !!!!!!!!        WARNING WARNING        !!!!!!!!!!!
2808    // !!!!!!!! Obscure copy of the old Image !!!!!!!!!!!
2809    const MFUInt8 srcPixel = *getMFPixel();
2810
2811    // set image data
2812
2813    destImage->set(PixelFormat(getPixelFormat()),
2814                   width,
2815                   height,
2816                   depth,
2817                   getMipMapCount(),
2818                   getFrameCount (),
2819                   getFrameDelay (),
2820                   0,
2821                   getDataType   (),
2822                   true,
2823                   getSideCount  ());
2824
2825    // copy every mipmap in every side in every frame
2826    for(frame = 0; frame < getFrameCount(); frame++)
2827    {
2828        for (side = 0; side < getSideCount(); side++)
2829        {
2830
2831            for(mipmap = 0; mipmap < getMipMapCount(); mipmap++)
2832            {
2833                // get the memory pointer
2834                src = (&(srcPixel[0])) +
2835                    (side  * getSideSize ()) +
2836                    (frame * getFrameSize()) ;
2837
2838                if(mipmap)
2839                {
2840                    src += calcMipmapSumSize (mipmap,
2841                                              oldWidth,
2842                                              oldHeight,
2843                                              oldDepth);
2844                }
2845
2846                dest = destImage->editData(mipmap, frame, side);
2847
2848                // calc the mipmap size
2849                sw = oldWidth  >> mipmap;
2850                sh = oldHeight >> mipmap;
2851                sd = oldDepth  >> mipmap;
2852
2853                destImage->calcMipmapGeometry(mipmap, dw, dh, dd);
2854
2855                // copy and scale the data
2856                scaleData(src, sw, sh, sd, dest, dw, dh, dd);
2857
2858            }
2859        }
2860    }
2861
2862    return true;
2863}
2864
2865/*! Mirror the image along horizontal, vertical, or depth.
2866    The method can operate on the object or stores the result in
2867    the optional destination Image.
2868 */
2869
2870bool Image::mirror(bool   horizontal,
2871                   bool   vertical,
2872                   bool   flipDepth,
2873                   Image *destination)
2874{
2875    if ( !horizontal && !vertical)
2876    {
2877        if(destination != NULL)
2878            *destination = *this;
2879        
2880        return true;
2881    }
2882
2883    Image *destImage;
2884
2885    if(destination != NULL)
2886    {
2887        destImage = destination;
2888    }
2889    else
2890    {
2891        destImage = this;
2892    }
2893
2894    // Get pixels.
2895    // !!!!!!!!        WARNING WARNING        !!!!!!!!!!!
2896    // !!!!!!!! Obscure copy of the old Image !!!!!!!!!!!
2897    const MFUInt8 srcPixel = (*getMFPixel());
2898
2899    UInt32 width = getWidth();
2900    UInt32 height = getHeight();
2901    UInt32 depth = getDepth();
2902
2903    destImage->set(PixelFormat(getPixelFormat()),
2904                   width,
2905                   height,
2906                   depth,
2907                   getMipMapCount(),
2908                   getFrameCount (),
2909                   getFrameDelay (),
2910                   0,
2911                   getDataType   (),
2912                   true,
2913                   getSideCount  ());
2914
2915    Int32         frame, side, mipmap;
2916    const UChar8 *src;
2917    UChar8       *dest;
2918
2919    // copy every mipmap in every side in every frame
2920    for(frame = 0; frame < getFrameCount(); frame++)
2921    {
2922        for (side = 0; side < getSideCount(); side++)
2923        {
2924            for(mipmap = 0; mipmap < getMipMapCount(); mipmap++)
2925            {
2926                // get the memory pointer
2927                src = (&(srcPixel[0])) +
2928                      (side  * getSideSize ()) +
2929                      (frame * getFrameSize());
2930
2931                if(mipmap)
2932                {
2933                    src += calcMipmapSumSize(mipmap, width, height, depth);
2934                }
2935
2936                dest = destImage->editData(mipmap, frame, side);
2937                destImage->calcMipmapGeometry(mipmap, width, height, depth);
2938
2939                // copy and mirror the data
2940                mirrorData(src, dest, width, height, depth, horizontal,
2941                           vertical, flipDepth);
2942            }
2943        }
2944    }
2945    return true;
2946}
2947
2948/*! Scale the image to the next power of 2 dimensions
2949    The method can operate on the object or stores the result in
2950    the optional destination Image.
2951 */
2952
2953bool Image::scaleNextPower2(Image *destination)
2954{
2955  return scale(osgNextPower2(getWidth ()),
2956               osgNextPower2(getHeight()),
2957               osgNextPower2(getDepth ()),
2958               destination              );
2959}
2960
2961/*! Crop the image to the given bounding box.
2962  The method can operate on the object or stores the result in
2963  the optional destination Image.
2964 */
2965
2966bool Image::subImage(Int32  offX,
2967                     Int32  offY,
2968                     Int32  offZ,
2969                     Int32  destW,
2970                     Int32  destH,
2971                     Int32  destD,
2972                     Image *destination)
2973{
2974    ImageUnrecPtr destImage(destination);
2975    bool          retCode   = true;
2976
2977    if (hasCompressedData())
2978    {
2979        FFATAL (("Invalid Image::subImage for compressed image\n"));
2980        return false;
2981    }
2982
2983    if(destination == NULL)
2984    {
2985        destImage = Image::create();
2986    }
2987
2988    destImage->set(PixelFormat(getPixelFormat()),
2989                   destW,
2990                   destH,
2991                   destD,
2992                   1,
2993                   1,
2994                   0.0,
2995                   0,
2996                   getDataType());
2997
2998    const UChar8  *src =            getData ();
2999          UChar8 *dest = destImage->editData();
3000
3001    FDEBUG(("Image::subImage (%d %d %d) - (%d %d %d) - destPtr %p\n",
3002            offX, offY, offZ, destW, destH, destD, dest));
3003
3004    // ensure destination data is zero
3005    memset(dest, 0, destImage->getSize());
3006
3007    // determine the area to actually copy
3008    UInt32 xMin = offX;
3009    UInt32 yMin = offY;
3010    UInt32 zMin = offZ;
3011
3012    UInt32 xMax = osgMin(getWidth (), offX + destW);
3013    UInt32 yMax = osgMin(getHeight(), offY + destH);
3014    UInt32 zMax = osgMin(getDepth (), offZ + destD);
3015
3016    // fill the destination buffer with the subdata
3017    UInt32 destIdx = 0;
3018
3019    for(UInt32 z = zMin; z < zMax; z++)
3020    {
3021        for(UInt32 y = yMin; y < yMax; y++)
3022        {
3023            for(UInt32 x = xMin; x < xMax; x++)
3024            {
3025                for(Int32 i = 0; i < getBpp(); i++)
3026                {
3027                    dest[destIdx] = src[((z * getHeight() + y) *
3028                                         getWidth() + x) * getBpp() + i];
3029                    destIdx++;
3030                }
3031            }
3032
3033            destIdx += (destW - (xMax - xMin)) * getBpp();
3034        }
3035
3036        destIdx += (destH - (yMax - yMin)) * destW * getBpp();
3037    }
3038
3039    // rip the data from the local destImage if necessary
3040    if(destination == NULL)
3041    {
3042        this->set(destImage);
3043    }
3044
3045    return retCode;
3046}
3047
3048/*! Crop a slice.
3049  The method can operate on the object or stores the result in
3050  the optional destination Image.
3051 */
3052
3053bool Image::slice(Int32  offX,
3054                  Int32  offY,
3055                  Int32  offZ,
3056                  Image *destination)
3057{
3058    ImageUnrecPtr destImage(destination);
3059    bool          retCode   = true;
3060    UInt32        counter   = 0;
3061
3062    if (hasCompressedData())
3063    {
3064        FFATAL (("Invalid Image::slice for compressed image\n"));
3065        return false;
3066    }
3067
3068    if(destination == NULL)
3069    {
3070        destImage = Image::create();
3071    }
3072
3073    FDEBUG(("Image::slice (%d %d %d)\n",
3074            offX, offY, offZ));
3075
3076    if(offX >= 0)
3077        counter++;
3078
3079    if(offY >= 0)
3080        counter++;
3081
3082    if(offZ >= 0)
3083        counter++;
3084
3085    if(counter != 1)
3086    {
3087        FWARNING(("Image::slice - more/less than one non negative value\n"));
3088        return false;
3089    }
3090
3091    if(offZ >= 0)
3092    {
3093        // XY slice
3094        retCode = subImage(0,
3095                           0,
3096                           offZ,
3097                           getWidth (),
3098                           getHeight(),
3099                           1,
3100                           destImage );
3101    }
3102
3103    if(offY >= 0)
3104    {
3105        // XZ slice
3106        destImage->set(PixelFormat(getPixelFormat()),
3107                       getWidth(),
3108                       getDepth(),
3109                       1,
3110                       1,
3111                       1,
3112                       0.0,
3113                       0,
3114                       getDataType());
3115
3116        const UChar8 *src  =            getData ();
3117              UChar8 *dest = destImage->editData();
3118
3119        // ensure destination data is zero
3120        memset(dest, 0, destImage->getSize());
3121
3122        for(Int32 z = 0; z < getDepth(); z++)
3123        {
3124            for(Int32 x = 0; x < getWidth(); x++)
3125            {
3126                for(Int32 i = 0; i < getBpp(); i++)
3127                {
3128                    dest[(z * getWidth() + x) * getBpp() + i] =
3129                        src[((z * getHeight() + offY) * getWidth() + x) *
3130                            getBpp() + i];
3131                }
3132            }
3133        }
3134    }
3135
3136    if(offX >= 0)
3137    {
3138        // YZ slice
3139        destImage->set(PixelFormat(getPixelFormat()),
3140                       getWidth(),
3141                       getDepth(),
3142                       1,
3143                       1,
3144                       1,
3145                       0.0,
3146                       0,
3147                       getDataType());
3148
3149        const UChar8 *src  =            getData ();
3150              UChar8 *dest = destImage->editData();
3151
3152        // ensure destination data is zero
3153        memset(dest, 0, destImage->getSize());
3154
3155        for(Int32 z = 0; z < getDepth(); z++)
3156        {
3157            for(Int32 y = 0; y < getHeight(); y++)
3158            {
3159                for(Int32 i = 0; i < getBpp(); i++)
3160                {
3161                    dest[(z * getHeight() + y) * getBpp() + i] =
3162                        src[((z * getHeight() + y) * getWidth() + offX) *
3163                            getBpp() + i];
3164                }
3165            }
3166        }
3167    }
3168
3169    // rip the data from the local destImage if necessary
3170    if(destination == NULL)
3171    {
3172        this->set(destImage);
3173    }
3174
3175    return retCode;
3176}
3177
3178/*! Create mipmaps data, level defines the number of level
3179  The method can operate on the object or stores the result in
3180  the optional destination Image.
3181 */
3182
3183bool Image::createMipmap(Int32 level, Image *destination)
3184{
3185    struct Offset
3186    {
3187        Int32   d;
3188        Int32   h;
3189        Int32   w;
3190    };
3191
3192    Offset  offset[][8] =
3193    {
3194        {   // 000
3195            { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
3196            { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
3197        },
3198        {   // 100
3199            { 0, 0, 0 }, { 1, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
3200            { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
3201        },
3202        {   // 010
3203            { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
3204            { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
3205        },
3206        {   // 110
3207            { 0, 0, 0 }, { 0, 1, 0 }, { 1, 0, 0 }, { 1, 1, 0 },
3208            { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
3209        },
3210        {   // 001
3211            { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 0 },
3212            { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
3213        },
3214        {   // 101
3215            { 0, 0, 0 }, { 1, 0, 0 }, { 0, 0, 1 }, { 1, 0, 1 },
3216            { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
3217        },
3218        {   // 011
3219            { 0, 0, 0 }, { 0, 0, 1 }, { 0, 1, 0 }, { 0, 1, 1 },
3220            { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
3221        },
3222        {   // 111
3223            { 0, 0, 0 }, { 1, 0, 0 }, { 0, 1, 0 }, { 1, 1, 0 },
3224            { 0, 0, 1 }, { 1, 0, 1 }, { 0, 1, 1 }, { 1, 1, 1 }
3225        }
3226    };
3227
3228    Int32   offsetSize[] = { 0, 2, 2, 4, 2, 4, 4, 8 };
3229
3230    ImageUnrecPtr destImage(destination);
3231
3232    Int32   w = getWidth(), h = getHeight(), d = getDepth();
3233    Int32   wm, hm, dm, wi, hi, di;
3234
3235    const UChar8  *src;
3236          UChar8  *dest;
3237    const UInt16 *sourceDataUC16;
3238          UInt16 *destDataUC16;
3239    const UInt32 *sourceDataUC32;
3240          UInt32 *destDataUC32;
3241    const Real32 *sourceDataF32;
3242          Real32 *destDataF32;
3243    const Real16 *sourceDataH16;
3244          Real16 *destDataH16;
3245
3246    if (hasCompressedData())
3247    {
3248        FFATAL (("Invalid Image::createMipmap for compressed image\n"));
3249        return false;
3250    }
3251
3252    if(destImage == NULL)
3253    {
3254        destImage = Image::create();
3255    }
3256
3257    Real32 valueFloat;
3258    Int32  value, i, elem, dim, side, frame, size, mipmap;
3259    Int32  channel, lineSize, sliceSize;
3260
3261    // calc the level count
3262    if(level < 0)
3263    {
3264        level = calcMipmapLevelCount();
3265    }
3266
3267    // create destination image
3268    destImage->set(getPixelFormat(),
3269                   getWidth(),
3270                   getHeight(),
3271                   getDepth(),
3272                   level,
3273                   getFrameCount(),
3274                   getFrameDelay(),
3275                   0,
3276                   getDataType(),
3277                   true,
3278                   getSideCount());
3279
3280    // copy the data;
3281    switch (getDataType())
3282    {
3283        case OSG_UINT8_IMAGEDATA:
3284
3285            for(frame = 0; frame < getFrameCount(); frame++)
3286            {
3287                for(side = 0; side < getSideCount(); side++)
3288                {
3289                    src = this      ->getData (0, frame, side);
3290                    dest = destImage->editData(0, frame, side);
3291
3292                    size = getWidth() * getHeight() * getDepth() * getBpp();
3293
3294                    memcpy(dest, src, size);
3295
3296                    src = dest;
3297
3298                    dest = dest + size;
3299
3300                    w = getWidth ();
3301                    h = getHeight();
3302                    d = getDepth ();
3303
3304                    for(mipmap = 1; mipmap < level; mipmap++)
3305                    {
3306                        lineSize  = w *     getBpp();
3307                        sliceSize = w * h * getBpp();
3308
3309                        wm = (w == 1) ? w : (w >> 1);
3310                        hm = (h == 1) ? h : (h >> 1);
3311                        dm = (d == 1) ? d : (d >> 1);
3312
3313                        dim = (d > dm) * 1 + (h > hm) * 2 + (w > wm) * 4;
3314
3315                        elem = offsetSize[dim];
3316
3317                        for(di = 0; di < dm; di++)
3318                        {
3319                            for(hi = 0; hi < hm; hi++)
3320                            {
3321                                for(wi = 0; wi < wm; wi++)
3322                                {
3323                                    for(channel = 0; channel < getBpp(); channel++)
3324                                    {
3325                                        value = 0;
3326
3327                                        for(i = 0; i < elem; i++)
3328                                        {
3329                                            value += src[
3330                                                ((wi * 2) + offset[dim][i].w) * getBpp() +
3331                                                ((hi * 2) + offset[dim][i].h) * lineSize +
3332                                                ((di * 2) + offset[dim][i].d) * sliceSize +
3333                                                channel];
3334                                        }
3335
3336                                        *dest++ = Int8(value / elem);
3337                                    }
3338                                }
3339                            }
3340                        }
3341
3342                        src += sliceSize;
3343
3344                        w = wm;
3345                        h = hm;
3346                        d = dm;
3347                  }
3348                }
3349            }
3350            break;
3351
3352        case OSG_UINT16_IMAGEDATA:
3353
3354            for(frame = 0; frame < getFrameCount(); frame++)
3355            {
3356                for(side = 0; side < getSideCount(); side++)
3357                {
3358                    src  = this     ->getData (0, frame, side);
3359                    dest = destImage->editData(0, frame, side);
3360
3361                    size = getWidth() * getHeight() * getDepth() * getBpp();
3362
3363                    memcpy(dest, src, size);
3364
3365                    src  = dest;
3366                    dest = dest + size;
3367
3368                    w = getWidth ();
3369                    h = getHeight();
3370                    d = getDepth ();
3371
3372                    sourceDataUC16 = reinterpret_cast<const UInt16 *>(src );
3373                    destDataUC16   = reinterpret_cast<      UInt16 *>(dest);
3374
3375                    for(mipmap = 1; mipmap < level; mipmap++)
3376                    {
3377                        lineSize  = w *     (getBpp() / getComponentSize());
3378                        sliceSize = w * h * (getBpp() / getComponentSize());
3379
3380                        wm = (w == 1) ? w : (w >> 1);
3381                        hm = (h == 1) ? h : (h >> 1);
3382                        dm = (d == 1) ? d : (d >> 1);
3383
3384                        dim = (d > dm) * 1 + (h > hm) * 2 + (w > wm) * 4;
3385
3386                        elem = offsetSize[dim];
3387
3388                        for(di = 0; di < dm; di++)
3389                        {
3390                            for(hi = 0; hi < hm; hi++)
3391                            {
3392                                for(wi = 0; wi < wm; wi++)
3393                                {
3394                                    for(channel = 0;
3395                                        channel < (getBpp() / getComponentSize());
3396                                        channel++)
3397                                    {
3398                                        value = 0;
3399
3400                                        for(i = 0; i < elem; i++)
3401                                        {
3402                                            value += sourceDataUC16[
3403                                                ((wi * 2) + offset[dim][i].w) * (getBpp() / getComponentSize()) +
3404                                                ((hi * 2) + offset[dim][i].h) * lineSize +
3405                                                ((di * 2) + offset[dim][i].d) * sliceSize +
3406                                                channel];
3407                                        }
3408
3409                                        *destDataUC16++ = UInt16(value / elem);
3410                                    }
3411                                }
3412                            }
3413                        }
3414
3415                        sourceDataUC16 += sliceSize;
3416
3417                        w = wm;
3418                        h = hm;
3419                        d = dm;
3420                    }
3421                }
3422            }
3423            break;
3424
3425        case OSG_UINT32_IMAGEDATA:
3426
3427            for(frame = 0; frame < getFrameCount(); frame++)
3428            {
3429                for(side = 0; side < getSideCount(); side++)
3430                {
3431                    src  = this     ->getData (0, frame,side);
3432                    dest = destImage->editData(0, frame,side);
3433
3434                    size = getWidth() * getHeight() * getDepth() * getBpp();
3435
3436                    memcpy(dest, src, size);
3437
3438                    src  = dest;
3439                    dest = dest + size;
3440
3441                    w = getWidth ();
3442                    h = getHeight();
3443                    d = getDepth ();
3444
3445                    sourceDataUC32 = reinterpret_cast<const UInt32 *>(src );
3446                    destDataUC32   = reinterpret_cast<      UInt32 *>(dest);
3447
3448                    for(mipmap = 1; mipmap < level; mipmap++)
3449                    {
3450                        lineSize  = w *     (getBpp() / getComponentSize());
3451                        sliceSize = w * h * (getBpp() / getComponentSize());
3452
3453                        wm = (w == 1) ? w : (w >> 1);
3454                        hm = (h == 1) ? h : (h >> 1);
3455                        dm = (d == 1) ? d : (d >> 1);
3456
3457                        dim = (d > dm) * 1 + (h > hm) * 2 + (w > wm) * 4;
3458
3459                        elem = offsetSize[dim];
3460
3461                        for(di = 0; di < dm; di++)
3462                        {
3463                            for(hi = 0; hi < hm; hi++)
3464                            {
3465                                for(wi = 0; wi < wm; wi++)
3466                                {
3467                                    for(channel = 0;
3468                                        channel < (getBpp()/getComponentSize());
3469                                        channel++)
3470                                    {
3471                                        value = 0;
3472
3473                                        for(i = 0; i < elem; i++)
3474                                        {
3475                                            value += (sourceDataUC32[
3476                                                          ((wi * 2) + offset[dim][i].w) * (getBpp() / getComponentSize()) +
3477                                                          ((hi * 2) + offset[dim][i].h) * lineSize +
3478                                                          ((di * 2) + offset[dim][i].d) * sliceSize +
3479                                                          channel]/elem);
3480                                        }
3481                                        *destDataUC32++ = UInt32(value);
3482                                    }
3483                                }
3484                            }
3485                        }
3486
3487                        sourceDataUC32 += sliceSize;
3488
3489                        w = wm;
3490                        h = hm;
3491                        d = dm;
3492                    }
3493                }
3494            }
3495            break;
3496
3497        case OSG_FLOAT32_IMAGEDATA:
3498
3499            for(frame = 0; frame < getFrameCount(); frame++)
3500            {
3501                for(side = 0; side < getSideCount(); side++)
3502                {
3503                    src  = this     ->getData (0, frame,side);
3504                    dest = destImage->editData(0, frame,side);
3505
3506                    size = getWidth() * getHeight() * getDepth() * getBpp();
3507
3508                    memcpy(dest, src, size);
3509
3510                    src  = dest;
3511                    dest = dest + size;
3512
3513                    w = getWidth ();
3514                    h = getHeight();
3515                    d = getDepth ();
3516
3517                    sourceDataF32 = reinterpret_cast<const Real32 *>(src );
3518                    destDataF32   = reinterpret_cast<      Real32 *>(dest);
3519
3520                    for(mipmap = 1; mipmap < level; mipmap++)
3521                    {
3522                        lineSize  = w *     (getBpp() / getComponentSize());
3523                        sliceSize = w * h * (getBpp() / getComponentSize());
3524
3525                        wm = (w == 1) ? w : (w >> 1);
3526                        hm = (h == 1) ? h : (h >> 1);
3527                        dm = (d == 1) ? d : (d >> 1);
3528
3529                        dim = (d > dm) * 1 + (h > hm) * 2 + (w > wm) * 4;
3530
3531                        elem = offsetSize[dim];
3532
3533                        for(di = 0; di < dm; di++)
3534                        {
3535                            for(hi = 0; hi < hm; hi++)
3536                            {
3537                                for(wi = 0; wi < wm; wi++)
3538                                {
3539                                    for(channel = 0;
3540                                        channel < (getBpp() / getComponentSize());
3541                                        channel++)
3542                                    {
3543                                        valueFloat = 0;
3544
3545                                        for(i = 0; i < elem; i++)
3546                                        {
3547                                            valueFloat += sourceDataF32[
3548                                                ((wi * 2) + offset[dim][i].w) * (getBpp() / getComponentSize()) +
3549                                                ((hi * 2) + offset[dim][i].h) * lineSize +
3550                                                ((di * 2) + offset[dim][i].d) * sliceSize +
3551                                                channel];
3552                                        }
3553
3554                                        *destDataF32++ = Real32(valueFloat / elem);
3555                                    }
3556                                }
3557                            }
3558                        }
3559
3560                        sourceDataF32 += sliceSize;
3561
3562                        w = wm;
3563                        h = hm;
3564                        d = dm;
3565                    }
3566                }
3567            }
3568            break;
3569
3570        case OSG_FLOAT16_IMAGEDATA:
3571            for(frame = 0; frame < getFrameCount(); frame++)
3572            {
3573                for(side = 0; side < getSideCount(); side++)
3574                {
3575                    src = this->getData(0, frame,side);
3576                    dest = destImage->editData(0, frame,side);
3577                    size = getWidth() * getHeight() * getDepth() * getBpp();
3578                    memcpy(dest,src, size);
3579                    src = dest;
3580                    dest = dest + size;
3581                    w = getWidth();
3582                    h = getHeight();
3583                    d = getDepth();
3584
3585                    sourceDataH16 = reinterpret_cast<const Real16 *>(src );
3586                    destDataH16   = reinterpret_cast<      Real16 *>(dest);
3587
3588                    for(mipmap = 1; mipmap < level; mipmap++)
3589                    {
3590                        lineSize = w * (getBpp() / getComponentSize());
3591                        sliceSize = w * h * (getBpp() / getComponentSize());
3592                        wm = (w == 1) ? w : (w >> 1);
3593                        hm = (h == 1) ? h : (h >> 1);
3594                        dm = (d == 1) ? d : (d >> 1);
3595
3596                        dim = (d > dm) * 1 + (h > hm) * 2 + (w > wm) * 4;
3597                        elem = offsetSize[dim];
3598
3599                        for(di = 0; di < dm; di++)
3600                        {
3601                            for(hi = 0; hi < hm; hi++)
3602                            {
3603                                for(wi = 0; wi < wm; wi++)
3604                                {
3605                                    for(channel = 0; channel < (getBpp()/getComponentSize()); channel++)
3606                                    {
3607                                        valueFloat = 0;
3608                                        for(i = 0; i < elem; i++)
3609                                        {
3610                                            valueFloat += sourceDataH16[
3611                                                ((wi * 2) + offset[dim][i].w) * (getBpp() / getComponentSize()) +
3612                                                ((hi * 2) + offset[dim][i].h) * lineSize +
3613                                                ((di * 2) + offset[dim][i].d) * sliceSize +
3614                                                channel];
3615                                        }
3616                                        *destDataH16++ = Real16(valueFloat / elem);
3617                                    }
3618                                }
3619                            }
3620                        }
3621                        sourceDataH16 += sliceSize;
3622                        w = wm;
3623                        h = hm;
3624                        d = dm;
3625                    }
3626                }
3627            }
3628            break;
3629
3630		case OSG_INT16_IMAGEDATA:
3631		case OSG_INT32_IMAGEDATA:
3632        {
3633            FFATAL((" 'createMipmap' NYI\n "));
3634        }
3635        break;
3636
3637        default:
3638            FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
3639            break;
3640    }
3641
3642    // rip the data from the local destImage if necessary
3643    if(destination == NULL)
3644    {
3645        this->set(destImage);
3646    }
3647
3648    return true;
3649}
3650
3651bool Image::removeMipmap(void)
3652{
3653    if(getMipMapCount() == 1) // no mipmaps nothing to do.
3654        return true;
3655
3656    // create destination image
3657    ImageUnrecPtr destImage = Image::create();
3658
3659    destImage->set(getPixelFormat(),
3660                   getWidth      (), 
3661                   getHeight     (), 
3662                   getDepth      (),
3663                   1, 
3664                   getFrameCount (),
3665                   getFrameDelay (), 
3666                   NULL, 
3667                   getDataType   (),
3668                   true,
3669                   getSideCount  ());
3670
3671    if(!destImage->isValid())
3672    {
3673        destImage = NULL;
3674
3675        return false;
3676    }
3677
3678    // copy the data;
3679    for(Int32 frame = 0; frame < getFrameCount(); frame++)
3680    {
3681        for(Int32 side = 0; side < getSideCount(); side++) 
3682        {
3683            const UChar8 *src = this->getData(0, frame, side);
3684
3685            UChar8 *dest = destImage->editData(0, frame, side);
3686
3687            Int32 size = getWidth() * getHeight() * getDepth() * getBpp();
3688
3689            memcpy(dest,src, size);
3690        }
3691    }
3692
3693    this->set(destImage);
3694    
3695    destImage = NULL;
3696
3697    return true;
3698}
3699
3700/*! Write the image to the a file. The mimetype will be set automatically
3701  from the fileName suffix. Returns true on success.
3702 */
3703
3704bool Image::write(const Char8 *fileName)
3705{
3706    return ImageFileHandler::the()->write(this, fileName);
3707}
3708
3709/*! Read the image data from a file. Returns true on success.
3710 */
3711
3712bool Image::read(const Char8 *fileName)
3713{
3714    return ImageFileHandler::the()->read(this, fileName);
3715}
3716
3717
3718/*! Store the image to the given mem block as 'mimeType'.
3719  mimeType can be 0, in which case the method will store the
3720  object as uncompressed mtd data.
3721  Returns the number of bytes used.
3722 */
3723
3724UInt64 Image::store(const Char8 *mimeType, UChar8 *mem, Int32 memSize)
3725{
3726    return ImageFileHandler::the()->store(this,
3727                                          mimeType,
3728                                          mem,
3729                                          memSize);
3730}
3731
3732/*! Restore the image from the given mem block. Returns the
3733  number of bytes used.
3734 */
3735
3736UInt64 Image::restore(const UChar8 *mem, Int32 memSize)
3737{
3738    return ImageFileHandler::the()->restore(this, mem, memSize);;
3739}
3740
3741
3742/*-------------------------------------------------------------------------*/
3743/*                               Constructor / Destructor                  */
3744
3745/*! Default Constructor. Creates a invalid Image of the size 0x0x0
3746 */
3747
3748Image::Image(void) :
3749     Inherited   (),
3750    _mipmapOffset()
3751{
3752}
3753
3754/*! Copy Constructor. Creates a copy of the given image
3755 */
3756
3757Image::Image(const Image &obj) :
3758     Inherited   (obj              ),
3759    _mipmapOffset(obj._mipmapOffset)
3760{
3761}
3762
3763/*! Destructor.
3764 */
3765
3766Image::~Image(void)
3767{
3768}
3769
3770/*! Method to check, whether the object data defines a alpha channel or not
3771 */
3772
3773bool Image::hasAlphaChannel(void)
3774{
3775    return
3776        (getForceAlphaChannel() == true         ) ||
3777        (getPixelFormat      () == OSG_RGBA_PF  ) ||
3778        (getPixelFormat      () == OSG_BGRA_PF  ) ||
3779        (getPixelFormat      () == OSG_RGBA_DXT1) ||
3780        (getPixelFormat      () == OSG_RGBA_DXT3) ||
3781        (getPixelFormat      () == OSG_RGBA_DXT5) ||
3782        (getPixelFormat      () == OSG_A_PF     ) ||
3783        (getPixelFormat      () == OSG_I_PF     ) ||
3784        (getPixelFormat      () == OSG_LA_PF    ) ||
3785
3786        (getPixelFormat      () == OSG_ALPHA_INTEGER_PF          ) ||
3787        (getPixelFormat      () == OSG_RGBA_INTEGER_PF           ) ||
3788        (getPixelFormat      () == OSG_BGRA_INTEGER_PF           ) ||
3789        (getPixelFormat      () == OSG_LUMINANCE_ALPHA_INTEGER_PF);
3790}
3791
3792/*! Method to check, whether the alpha channel is just fully transparent/
3793    fully opaque
3794 */
3795bool Image::isAlphaBinary(void)
3796{
3797    return
3798        (getForceAlphaBinary() == true         ) ||
3799        (getPixelFormat     () == OSG_RGBA_DXT1);
3800}
3801
3802/*! Method to check, whether the data is compressed
3803 */
3804bool Image::hasCompressedData(void)
3805{
3806  return
3807      (getForceCompressedData() == true         ) ||
3808      (getPixelFormat        () == OSG_RGB_DXT1 ) ||
3809      (getPixelFormat        () == OSG_RGBA_DXT1) ||
3810      (getPixelFormat        () == OSG_RGBA_DXT3) ||
3811      (getPixelFormat        () == OSG_RGBA_DXT5);
3812
3813}
3814
3815/*! Method to check, whether the object data defines a color channel or not
3816 */
3817bool Image::hasColorChannel(void)
3818{
3819    return
3820        ( !( getPixelFormat() == OSG_A_PF  ||
3821             getPixelFormat() == OSG_I_PF  ||
3822             getPixelFormat() == OSG_L_PF  ||
3823             getPixelFormat() == OSG_LA_PF ||
3824
3825             getPixelFormat() == OSG_ALPHA_INTEGER_PF          ||
3826             getPixelFormat() == OSG_LUMINANCE_ALPHA_INTEGER_PF )) ||
3827        getForceColorChannel();
3828}
3829
3830/*! Method returns the right frame data for the given time.
3831 */
3832
3833const UInt8 *Image::getDataByTime(Time time, UInt32) const
3834{
3835    UInt32 frameNum = calcFrameNum(time, true);
3836
3837    return getData(0, frameNum);
3838}
3839
3840UInt8 *Image::editDataByTime(Time time, UInt32)
3841{
3842    UInt32 frameNum = calcFrameNum(time, true);
3843
3844    return editData(0, frameNum);
3845}
3846
3847/*! Check all the alpha values to see if they're 0 or 1, return true if they
3848  are, false if no alpha or intermediate values. No Alpha channel is considered
3849  0.
3850 */
3851
3852bool Image::calcIsAlphaBinary(void)
3853{
3854    if(!hasAlphaChannel() || getPixelFormat() == OSG_RGBA_DXT1)
3855        return true;
3856
3857    if(getPixelFormat() == OSG_RGBA_DXT3 || getPixelFormat() == OSG_RGBA_DXT5)
3858    {
3859        FWARNING(("Image::calcIsAlphaBinary: not implemenetd for DXT3 "
3860                  "and DXT5 yet, assuming false.\n"));
3861        return false;
3862    }
3863
3864    UInt32 npix = getWidth() * getHeight() * getDepth() * getFrameCount();
3865    UInt8 pixelsize = getBpp();
3866
3867    const UInt8 *data = getData();
3868
3869    switch(getPixelFormat())
3870    {
3871        case OSG_LA_PF:
3872            data += getComponentSize(); break;
3873        case OSG_BGRA_PF:
3874        case OSG_RGBA_PF:
3875            data += getComponentSize() * 3; break;
3876        default:
3877            FWARNING(("Image::calcIsAlphaBinary: found unknown "
3878                      "image format %x, assumning false.\n",
3879                      getPixelFormat()));
3880            return false;
3881    }
3882
3883    switch(getDataType())
3884    {
3885        case OSG_UINT8_IMAGEDATA:
3886            for(; npix > 0; --npix, data += pixelsize)
3887            {
3888                if(*data != 0 && *data != 0xffU)
3889                    break;
3890            }
3891            break;
3892        case OSG_UINT16_IMAGEDATA:
3893            for(; npix > 0; --npix, data += pixelsize)
3894            {
3895                const UInt16 *d = reinterpret_cast<const UInt16*>(data);
3896                if(*d != 0 && *d != 0xffffU)
3897                    break;
3898            }
3899            break;
3900        case OSG_UINT32_IMAGEDATA:
3901            for(; npix > 0; --npix, data += pixelsize)
3902            {
3903                const UInt32 *d = reinterpret_cast<const UInt32*>(data);
3904                if(*d != 0 && *d != 0xffffffffU)
3905                    break;
3906            }
3907            break;
3908        case OSG_FLOAT16_IMAGEDATA:
3909            for(; npix > 0; --npix, data += pixelsize)
3910            {
3911                const Real16 *d = reinterpret_cast<const Real16*>(data);
3912                if(*d != 0 && *d != 1)
3913                    break;
3914            }
3915            break;
3916        case OSG_FLOAT32_IMAGEDATA:
3917            for(; npix > 0; --npix, data += pixelsize)
3918            {
3919                const Real32 *d = reinterpret_cast<const Real32*>(data);
3920                if(*d != 0 && *d != 1)
3921                    break;
3922            }
3923            break;
3924        case OSG_INT16_IMAGEDATA:
3925        case OSG_INT32_IMAGEDATA:
3926		{
3927			FFATAL((" 'calcIsAlphaBinary' NYI\n "));
3928		}
3929		break;
3930
3931        default:
3932            FWARNING(("Image::calcIsAlphaBinary: found unknown "
3933                      "data type %d, assumning false.\n",
3934                      getDataType()));
3935            return false;
3936    }
3937
3938    return npix == 0;
3939}
3940
3941/*! Method which returns the frame number for the given time
3942 */
3943UInt32 Image::calcFrameNum(Time time, bool OSG_CHECK_ARG(loop)) const
3944{
3945    UInt64 frameNum = ((getFrameDelay() > 0) && (getFrameCount() > 0)) ?
3946        (UInt64(time / getFrameDelay()) % getFrameCount()) : 0;
3947
3948    return ((frameNum > 0) ? UInt32(frameNum) : 0);
3949}
3950
3951/*! Internal used method to calculate the next mipmap geo for the given level
3952 */
3953void Image::calcMipmapGeometry(UInt32 mipmapNum,
3954                               UInt32 &width,
3955                               UInt32 &height,
3956                               UInt32 &depth   ) const
3957{
3958    width  = getWidth()  ? osgMax(getWidth () >> mipmapNum, 1) : 0 ;
3959    height = getHeight() ? osgMax(getHeight() >> mipmapNum, 1) : 0 ;
3960    depth  = getDepth()  ? osgMax(getDepth () >> mipmapNum, 1) : 0 ;
3961}
3962
3963#ifdef __sgi
3964#pragma set woff 1209
3965#endif
3966
3967/*! Internal used method to calculate the number of mipmaps levels
3968 */
3969UInt32 Image::calcMipmapLevelCount(void) const
3970{
3971    UInt32  w = getWidth(), h = getHeight(), d = getDepth();
3972    UInt32 level;
3973
3974    for (level = 1; true; level++)
3975    {
3976        if ((w == 1) && (h == 1) && (d == 1))
3977        {
3978            break;
3979        }
3980        else
3981        {
3982            w = (w >>= 1) ? w : 1;
3983            h = (h >>= 1) ? h : 1;
3984            d = (d >>= 1) ? d : 1;
3985        }
3986    }
3987    return level;
3988}
3989
3990#ifdef __sgi
3991#pragma reset woff 1209
3992#endif
3993
3994/*-------------------------------------------------------------------------*/
3995/*                            Calculate Mipmap Size                        */
3996
3997/*! Method to calculate the mem sum of a mipmap level in byte
3998 */
3999UInt32 Image::calcMipmapLevelSize ( UInt32 mipmapNum,
4000                                    UInt32 w, UInt32 h, UInt32 d) const
4001{
4002    Int32 sum;
4003
4004    switch (getPixelFormat())
4005    {
4006        case OSG_RGB_DXT1:
4007        case OSG_RGBA_DXT1:
4008            sum = (((w?w:1)+3)/4) * (((h?h:1)+3)/4) * 8;
4009            break;
4010        case OSG_RGBA_DXT3:
4011        case OSG_RGBA_DXT5:
4012            sum = (((w?w:1)+3)/4) * (((h?h:1)+3)/4) * 16;
4013            break;
4014        default:
4015            sum = (w?w:1) * (h?h:1) * getBpp();
4016            break;
4017    }
4018
4019    sum *= (d?d:1);
4020
4021    return sum;
4022}
4023
4024/*! Internal used method to calculate the size in bpp of a single mipmap
4025  level for the current image settings
4026 */
4027
4028UInt32 Image::calcMipmapLevelSize(UInt32 mipmapNum) const
4029{
4030    UInt32 w, h, d;
4031    calcMipmapGeometry(mipmapNum, w, h, d);
4032    return calcMipmapLevelSize(mipmapNum, w, h, d);
4033}
4034
4035/*! Internal used method to calculate the mem sum of all mipmap levels in bpp
4036 */
4037
4038UInt32 Image::calcMipmapSumSize(UInt32 mipmapNum,
4039                                UInt32 w,
4040                                UInt32 h,
4041                                UInt32 d) const
4042{
4043    Int32 sum = 0;
4044
4045    if (w && h && d)
4046    {
4047        while (mipmapNum--)
4048        {
4049            sum += calcMipmapLevelSize(mipmapNum,w,h,d);
4050
4051            w >>= 1;
4052            h >>= 1;
4053            d >>= 1;
4054        }
4055    }
4056
4057    return sum;
4058}
4059
4060/*! Method to calculate the mem sum of all mipmap levels in byte
4061  for the current Image paramter
4062 */
4063UInt32 Image::calcMipmapSumSize (UInt32 mipmapNum) const
4064{
4065    return calcMipmapSumSize(mipmapNum, getWidth(), getHeight(), getDepth());
4066}
4067
4068/*-------------------------------------------------------------------------*/
4069/*                            Image data                                   */
4070
4071/*! Internal method to set the data and update related properties.
4072 */
4073
4074bool Image::createData(const UInt8 *data, bool allocMem)
4075{
4076    Int32 i;
4077    Int32 mapSizeFormat = sizeof(_formatDic) / sizeof(UInt32[2]);
4078    Int32 mapSizeType   = sizeof(_typeDic  ) / sizeof(UInt32[2]);
4079
4080    UInt32 byteCount = 0;
4081
4082    // set bpp
4083    UInt32 pixelFormat = 0;
4084    UInt32 typeFormat  = 0;
4085
4086    for(i = 0; i < mapSizeFormat; i++)
4087    {
4088        if(_formatDic[i][0] == getPixelFormat())
4089            pixelFormat = _formatDic[i][1];
4090    }
4091
4092    for(i = 0; i < mapSizeType; i++)
4093    {
4094        if(_typeDic[i][0] == getDataType())
4095            typeFormat = _typeDic[i][1];
4096    }
4097
4098    setComponentSize(typeFormat              );
4099    setBpp          (pixelFormat * typeFormat);
4100
4101    // set dimension
4102    setDimension(0);
4103
4104    if(getDepth() == 1)
4105    {
4106        if(getHeight() == 1)
4107        {
4108            setDimension(1);
4109        }
4110        else
4111        {
4112            setDimension(2);
4113        }
4114    }
4115    else
4116    {
4117        setDimension(3);
4118    }
4119
4120    // set sideSize
4121	UInt32 mipmapSumSize = calcMipmapSumSize(getMipMapCount());
4122    setSideSize (mipmapSumSize);
4123
4124    // set frameSize
4125    setFrameSize(getSideSize() * getSideCount());
4126
4127
4128    // copy the data
4129    if(allocMem && (byteCount = getSize()))
4130    {
4131        if(getMFPixel()->size() != byteCount)
4132        {
4133            try
4134            {
4135                if(byteCount < getMFPixel()->size())
4136                {
4137                    editMFPixel()->clear();
4138                    // free unused memory.
4139                    MFUInt8 tmp;
4140                    tmp.swap(*editMFPixel());
4141                }
4142                editMFPixel()->resize(byteCount);
4143            }
4144            catch(...)
4145            {
4146                FFATAL(("Image::createData : Couldn't allocate %u bytes!\n",
4147                        byteCount));
4148
4149                return false;
4150            }
4151        }
4152
4153        if(data)
4154        {
4155            memcpy(editData(), data, byteCount);
4156        }
4157    }
4158    else
4159    {
4160        editMFPixel()->clear();
4161    }
4162
4163    return (getData() != NULL);
4164}
4165
4166/*! Internal method to scale image data blocks
4167 */
4168bool Image::scaleData(const UInt8 *srcData,
4169                            Int32  srcW,
4170                            Int32  srcH,
4171                            Int32  srcD,
4172                            UInt8 *destData,
4173                            Int32  destW,
4174                            Int32  destH,
4175                            Int32  destD   )
4176{
4177    Real32  sx = Real32(srcW) / Real32(destW);
4178    Real32  sy = Real32(srcH) / Real32(destH);
4179    Real32  sz = Real32(srcD) / Real32(destD);
4180
4181    Int32   srcSize = srcW * srcH * srcD * getBpp();
4182
4183    //  Int32 destDize = destW * destH * destD;
4184
4185    Int32   x, y, z, p;
4186    const UInt8  *slice;
4187    const UInt8  *line;
4188    const UInt8  *pixel;
4189
4190    if(destW == srcW && destH == srcH && destD == srcD)
4191    {
4192        // same size, just copy
4193        memcpy(destData, srcData, srcSize);
4194    }
4195    else
4196    {       // different size, to 'nearest' copy
4197        for(z = 0; z < destD; z++)
4198        {
4199            slice = srcData + int(sz * z) * getBpp() * srcW * srcH;
4200
4201            for(y = 0; y < destH; y++)
4202            {
4203                line = slice + int(sy * y) * getBpp() * srcW;
4204
4205                for(x = 0; x < destW; x++)
4206                {
4207                    pixel = line + int(sx * x) * getBpp();
4208
4209                    p = getBpp();
4210
4211                    while(p--)
4212                    {
4213                        *destData++ = *pixel++;
4214                    }
4215                }
4216            }
4217        }
4218    }
4219
4220    return true;
4221}
4222
4223void Image::calcMipmapOffsets(void)
4224{
4225    UInt32 mipMapCount = getMipMapCount();
4226    
4227    if(mipMapCount == 0)
4228        mipMapCount = 1;
4229
4230    _mipmapOffset.resize(mipMapCount);
4231
4232    /*
4233    for(UInt32 i=0;i<mipMapCount;++i)
4234        _mipmapOffset[i] = calcMipmapSumSize[i];
4235    */
4236
4237    Int32 sum = 0;
4238
4239    UInt32 w = getWidth ();
4240    UInt32 h = getHeight();
4241    UInt32 d = getDepth ();
4242
4243    _mipmapOffset[0] = 0;
4244
4245    for(UInt32 i=1;i<mipMapCount;++i)
4246    {
4247        sum += calcMipmapLevelSize(i,w,h,d);
4248
4249        _mipmapOffset[i] = sum;
4250
4251        w >>= 1;
4252        h >>= 1;
4253        d >>= 1;
4254    }
4255}
4256
4257/*! Internal method to mirror image data blocks
4258 */
4259bool Image::mirrorData(const UInt8 *srcData,
4260                             UInt8 *destData,
4261                             Int32  width,
4262                             Int32  height,
4263                             Int32  depth,
4264                             bool   horizontal,
4265                             bool   vertical,
4266                             bool   flipDepth)
4267{
4268    int dx_step = horizontal ? -1 : 1;
4269    int dx_start = horizontal ? width-1 : 0;
4270    int dy_step = vertical ? -1 : 1;
4271    int dy_start = vertical ? height-1 : 0;
4272    int dz_step = flipDepth ? -1 : 1;
4273    int dz_start = flipDepth ? depth-1 : 0;
4274
4275    int dz = dz_start;
4276    for(int sz = 0; sz < depth; sz++, dz += dz_step)
4277    {
4278        const UInt8 *src_slice = srcData + (sz * getBpp() * width * height);
4279        UInt8       *dst_slice = destData + (dz * getBpp() * width * height);
4280        int dy = dy_start;
4281        for(int sy = 0; sy < height; sy++, dy += dy_step)
4282        {
4283            const UInt8 *src_line = src_slice + (sy * getBpp() * width);
4284            UInt8       *dst_line = dst_slice + (dy * getBpp() * width);
4285            int dx = dx_start;
4286            for(int sx = 0; sx < width; sx++, dx += dx_step)
4287            {
4288                const UInt8 *src_pixel = src_line + (sx * getBpp());
4289                UInt8       *dst_pixel = dst_line + (dx * getBpp());
4290 
4291                Int32 p = getBpp();
4292 
4293                while(p--)
4294                {
4295                    *dst_pixel++ = *src_pixel++;
4296                }
4297             }
4298        }
4299    }
4300    return true;
4301}
4302
4303/*! Assign operator. Does a copy of the given Image object.
4304 */
4305
4306Image &Image::operator=(const Image &image)
4307{
4308    this->set(PixelFormat(image.getPixelFormat()),
4309              image.getWidth      (),
4310              image.getHeight     (),
4311              image.getDepth      (),
4312              image.getMipMapCount(),
4313              image.getFrameCount (),
4314              image.getFrameDelay (),
4315              image.getData       (),
4316              image.getDataType   (),
4317              true,
4318              image.getSideCount  ());
4319
4320    return *this;
4321}
4322
4323/*! Less operator; compares the data sizes of the two images
4324*/
4325bool Image::operator<(const Image &image)
4326{
4327    return (getSize() < image.getSize()) ? true : false;
4328}
4329
4330/*! Method to compare the object to another Image instance;
4331    Checks first all parameter and afterwards the Image data;
4332*/
4333
4334bool Image::operator ==(const Image &image)
4335{
4336    unsigned long   i, s = getSize();
4337
4338    if((getWidth      () == image.getWidth      ()) &&
4339       (getHeight     () == image.getHeight     ()) &&
4340       (getDepth      () == image.getDepth      ()) &&
4341       (getMipMapCount() == image.getMipMapCount()) &&
4342       (getFrameCount () == image.getFrameCount ()) &&
4343       (getFrameDelay () == image.getFrameDelay ()) &&
4344       (getPixelFormat() == image.getPixelFormat()) &&
4345       (getDataType   () == image.getDataType   ()) &&
4346       (getSideCount  () == image.getSideCount  ()))
4347
4348    {
4349        for(i = 0; i < s; ++i)
4350        {
4351            if(image.getData()[i] != getData()[i])
4352                return false;
4353        }
4354        return true;
4355    }
4356    return false;
4357}
4358
4359/*! Method to compare the object to another Image instance;
4360  Checks first all parameter and afterwards the Image data;
4361 */
4362
4363bool Image::operator !=(const Image &image)
4364{
4365    return !(*this == image);
4366}
4367
4368#if 0
4369/*! Explicitly notfies parents about a change of the image contents. This is
4370    not strictly required because they are notified anyways, but can be used
4371    for optimization by specifying only the area that has actually changed.
4372    
4373    \note Currently only TextureChunks are notified.
4374    
4375    \warning Successive calls to this function will overwrite the previously
4376    set dirty area. If an application makes changes to multiple regions
4377    they have to accumulated by the user before calling this function.
4378 */
4379void
4380Image::imageContentChanged(
4381    Int32 minX, Int32 maxX, Int32 minY, Int32 maxY, Int32 minZ, Int32 maxZ)
4382{
4383    MFFieldContainerPtr::iterator parentsIt  = _mfParents.begin();
4384    MFFieldContainerPtr::iterator parentsEnd = _mfParents.end  ();
4385    
4386    for(; parentsIt != parentsEnd; ++parentsIt)
4387    {
4388        TextureChunkPtr texParent = TextureChunkPtr::dcast(*parentsIt);
4389        
4390        if(texParent != NullFC)
4391        {
4392            texParent->imageContentChanged(minX, maxX, minY, maxY, minZ, maxZ);
4393        }
4394    }
4395}
4396#endif