dibconv.cpp

Go to the documentation of this file.
00001 // $Id: dibconv.cpp 1378 2006-06-28 11:12:55Z gerry $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 
00099 // DIB conversion routines from one depth to another
00100 
00101 /*
00102 */
00103 
00104 #include "camtypes.h"
00105 //#include "dibconv.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00106 #include "gdraw.h"                  // temp bodge
00107 #include "grndrgn.h"
00108 //#include "grndbmp.h"              // GRenderBitmap
00109 #include "GDrawIntf.h"
00110 //#include "fixmem.h"                   // CCMalloc, CCFree - in camtypes.h [AUTOMATICALLY REMOVED]
00111 //#include "dibutil.h"              // DIBUtil::ScanlineSize - in camtypes.h [AUTOMATICALLY REMOVED]
00112 //#include "palman.h"
00113 
00114 CC_IMPLEMENT_MEMDUMP( DIBConvert, CC_CLASS_MEMDUMP )
00115 
00116 #if defined(__WXGTK__)
00117 #define GetLastError() (0)
00118 #elif defined(__WXMAC__)
00119 #define GetLastError() (0)
00120 #endif
00121 
00122 // these classes are never referred to outside this source file, so they live in the .cpp
00123 class Conv32to32 : public DIBConvert
00124 {
00125 public:
00126     Conv32to32( UINT32 );
00127     ~Conv32to32();
00128 
00129     BOOL Convert( LPBYTE Input, LPBYTE Output, UINT32 Height, BOOL FirstStrip );
00130 
00131 private:
00132     BITMAPINFOHEADER SourceHeader;
00133     BITMAPINFOHEADER DestHeader;
00134 };
00135 
00136 // these classes are never referred to outside this source file, so they live in the .cpp
00137 class Conv32to24 : public DIBConvert
00138 {
00139 public:
00140     Conv32to24( UINT32 );
00141     ~Conv32to24();
00142 
00143     BOOL Convert( LPBYTE Input, LPBYTE Output, UINT32 Height, BOOL FirstStrip );
00144 
00145 private:
00146     BITMAPINFOHEADER SourceHeader;
00147     BITMAPINFOHEADER DestHeader;
00148 };
00149 
00150 // these classes are never referred to outside this source file, so they live in the .cpp
00151 class Conv32to8 : public DIBConvert
00152 {
00153 public:
00154     Conv32to8( UINT32, LPLOGPALETTE, UINT32 );
00155     ~Conv32to8();
00156 
00157     BOOL Convert( LPBYTE Input, LPBYTE Output, UINT32 Height, BOOL FirstStrip );
00158 
00159 private:
00160     BITMAPINFOHEADER SourceHeader;
00161     BITMAPINFOHEADER DestHeader;
00162     LPLOGPALETTE DestPalette;
00163     UINT32 Dither;
00164 };
00165 
00166 // these classes are never referred to outside this source file, so they live in the .cpp
00167 class Conv32to4 : public DIBConvert
00168 {
00169 public:
00170     Conv32to4( UINT32, LPLOGPALETTE, UINT32 );
00171     ~Conv32to4();
00172 
00173     BOOL Convert( LPBYTE Input, LPBYTE Output, UINT32 Height, BOOL FirstStrip );
00174 
00175 private:
00176     BITMAPINFOHEADER SourceHeader;
00177     BITMAPINFOHEADER DestHeader;
00178     LPLOGPALETTE DestPalette;
00179     UINT32 Dither;
00180 };
00181 
00182 // these classes are never referred to outside this source file, so they live in the .cpp
00183 class Conv32to1 : public DIBConvert
00184 {
00185 public:
00186     Conv32to1( UINT32, LPLOGPALETTE, UINT32 );
00187     ~Conv32to1();
00188 
00189     BOOL Convert( LPBYTE Input, LPBYTE Output, UINT32 Height, BOOL FirstStrip );
00190 
00191 private:
00192     BITMAPINFOHEADER SourceHeader;
00193     BITMAPINFOHEADER DestHeader;
00194     LPLOGPALETTE DestPalette;
00195     UINT32 Dither;
00196 };
00197 
00198 // these classes are never referred to outside this source file, so they live in the .cpp
00199 class Conv24to8 : public DIBConvert
00200 {
00201 public:
00202     Conv24to8( UINT32, LPLOGPALETTE, UINT32 );
00203     ~Conv24to8();
00204 
00205     BOOL Convert( LPBYTE Input, LPBYTE Output, UINT32 Height, BOOL FirstStrip );
00206 
00207 protected:
00208     void Convert24to32( INT32 PixelWidth, LPBYTE InputBits, LPBYTE OutputBits );
00209 
00210 private:
00211     BITMAPINFOHEADER SourceHeader;
00212     BITMAPINFOHEADER DestHeader;
00213     LPLOGPALETTE DestPalette;
00214     UINT32 Dither;
00215 
00216     LPBYTE InputBuffer32bpp;
00217 };
00218 
00219 
00220 /********************************************************************************************
00221 
00222 >   class Conv8to32 : public DIBConvert
00223 
00224     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00225     Created:    07/11/96
00226     Purpose:    An 8 to 32 bpp converter
00227 
00228 ********************************************************************************************/
00229 class Conv8to32 : public DIBConvert
00230 {
00231 public:
00232     Conv8to32( LPBITMAPINFO pSourceHeader );
00233 
00234     BOOL Convert( LPBYTE pInput, LPBYTE pOutput, UINT32 Height, BOOL FirstStrip );
00235 
00236 protected:
00237     LPBITMAPINFO    m_pSourceHeader;
00238 };
00239 
00240 
00241 
00242 /********************************************************************************************
00243 
00244 >   class Conv24to32 : public DIBConvert
00245 
00246     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00247     Created:    07/11/96
00248     Purpose:    A 24 to 32 bpp converter
00249 
00250 ********************************************************************************************/
00251 class Conv24to32 : public DIBConvert
00252 {
00253 public:
00254     Conv24to32( LPBITMAPINFO pSourceHeader );
00255 
00256     BOOL Convert( LPBYTE pInput, LPBYTE pOutput, UINT32 Height, BOOL FirstStrip );
00257 
00258 protected:
00259     LPBITMAPINFO    m_pSourceHeader;
00260 };
00261 
00262 
00263 
00264 
00265 
00266 
00267 
00268 #define new CAM_DEBUG_NEW
00269 
00270 GDrawContext* DIBConvert::ConvertContext = NULL;        // Pointer to conversion context for 8bpp
00271 
00272 
00273 /********************************************************************************************
00274 
00275 >   DIBConvert::DIBConvert()
00276 
00277     Author:     Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>?
00278     Created:    29/06/96
00279     Purpose:    Base class to convert bitmap depths
00280 
00281 ********************************************************************************************/
00282 DIBConvert::DIBConvert()
00283 {
00284 }
00285 
00286 DIBConvert::~DIBConvert()
00287 {
00288 }
00289 
00290 
00291 
00292 BOOL DIBConvert::Init()
00293 {
00294     if (ConvertContext == NULL)
00295         ConvertContext = new GDrawAsm();
00296 
00297     if (ConvertContext)
00298         ConvertContext->Init();
00299 
00300     // We don't really care if this doesn't work as it is an optimisation
00301     return(TRUE);
00302 }
00303 
00304 
00305 void DIBConvert::DeInit()
00306 {
00307     if (ConvertContext != NULL)
00308     {
00309         delete ConvertContext;
00310         ConvertContext = NULL;
00311     }
00312 }
00313 
00314 
00315 GDrawContext* DIBConvert::GetConvertContext(void)
00316 {
00317     if (ConvertContext != NULL)
00318         return(ConvertContext);
00319     else
00320         return(GRenderRegion::GetStaticDrawContext());
00321 }
00322 
00323 
00324 DIBConvert *DIBConvert::Create( UINT32 SourceDepth, UINT32 DestDepth, UINT32 Width, LPLOGPALETTE Palette, UINT32 DitherType )
00325 {
00326     ERROR2IF(DestDepth<=8 && Palette==NULL,NULL,"DIBConvert::Create null palette specified");
00327     
00328     switch(SourceDepth)
00329     {
00330     case 32:
00331         {
00332             switch(DestDepth)
00333             {
00334             case 24:
00335                 return new Conv32to24( Width );
00336             case 8:
00337                 return new Conv32to8( Width, Palette, DitherType );
00338             case 4:
00339                 return new Conv32to4( Width, Palette, DitherType );
00340             case 1:
00341                 return new Conv32to1( Width, Palette, DitherType );
00342             case 32:
00343                 return new Conv32to32( Width );
00344             default:
00345                 return NULL;
00346             }
00347         }
00348     case 24:
00349         {
00350             if (DestDepth==8)
00351                 return new Conv24to8( Width, Palette, DitherType );
00352         }
00353     default:
00354         return NULL;
00355     }
00356 
00357     return NULL;
00358 }
00359 
00360 
00361 /********************************************************************************************
00362 
00363 >   DIBConvert* DIBConvert::Create( LPBITMAPINFO pSourceHeader, UINT32 DestDepth, UINT32 DitherType )
00364 
00365     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00366     Created:    07/11/96
00367     Purpose:    Alternative Creation function
00368 
00369 ********************************************************************************************/
00370 DIBConvert* DIBConvert::Create( LPBITMAPINFO pSourceHeader, UINT32 DestDepth, UINT32 DitherType )
00371 {
00372     DitherType = DitherType;
00373     UINT32 SourceDepth = pSourceHeader->bmiHeader.biBitCount;
00374 
00375     if (SourceDepth == 8)
00376     {
00377         if (DestDepth==32)
00378             return new Conv8to32( pSourceHeader );
00379     }
00380     if (SourceDepth == 24)
00381     {
00382         if (DestDepth==32)
00383             return new Conv24to32( pSourceHeader );
00384     }
00385     return NULL;
00386 }
00387 
00388 
00389 /********************************************************************************************
00390 
00391 >   Conv32to32::Conv32to32(UINT32 Width)
00392 
00393     Author:     Mark_Howitt (Xara Group Ltd) <camelotdev@xara.com>
00394     Created:    19/7/99
00395     Purpose:    Constructor
00396 
00397 ********************************************************************************************/
00398 Conv32to32::Conv32to32(UINT32 Width)
00399 {
00400     SourceHeader.biPlanes = 1;
00401     SourceHeader.biBitCount = 32;
00402     SourceHeader.biWidth = Width;
00403     SourceHeader.biClrUsed = 0;
00404 
00405     DestHeader.biPlanes = 1;
00406     DestHeader.biBitCount = 32;
00407     DestHeader.biWidth = Width;
00408     DestHeader.biClrUsed = 0;
00409 }
00410 
00411 Conv32to32::~Conv32to32()
00412 {
00413 }
00414 
00415 BOOL Conv32to32::Convert( LPBYTE Input, LPBYTE Output, UINT32 Height, BOOL FirstStrip )
00416 {
00417     SourceHeader.biHeight = Height;
00418 
00419     DestHeader.biHeight = Height;
00420 
00421     DWORD DitherWord = 0;
00422 
00423     GDrawContext *GDC = GetConvertContext();
00424     const BOOL res = GDC->ConvertBitmap( &SourceHeader, Input, &DestHeader, Output, DitherWord);
00425     if (!res)
00426         TRACE( _T("GColour_ConvertBitmap did error %x\n"), GetLastError() );
00427 
00428     return TRUE;
00429 }
00430 
00431 
00432 /********************************************************************************************
00433 
00434 >   Conv32to24::Conv32to24(UINT32 Width)
00435 
00436     Author:     Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>?
00437     Created:    29/06/96
00438     Purpose:    Constructor
00439 
00440 ********************************************************************************************/
00441 Conv32to24::Conv32to24(UINT32 Width)
00442 {
00443     SourceHeader.biPlanes = 1;
00444     SourceHeader.biBitCount = 32;
00445     SourceHeader.biWidth = Width;
00446     SourceHeader.biClrUsed = 0;
00447 
00448     DestHeader.biPlanes = 1;
00449     DestHeader.biBitCount = 24;
00450     DestHeader.biWidth = Width;
00451     DestHeader.biClrUsed = 0;
00452 }
00453 
00454 Conv32to24::~Conv32to24()
00455 {
00456 }
00457 
00458 BOOL Conv32to24::Convert( LPBYTE Input, LPBYTE Output, UINT32 Height, BOOL FirstStrip )
00459 {
00460     SourceHeader.biHeight = Height;
00461 
00462     DestHeader.biHeight = Height;
00463 
00464     DWORD DitherWord = 8;   // Convert to 888 format
00465 
00466     GDrawContext *GDC = GetConvertContext();
00467     const BOOL res = GDC->ConvertBitmap( &SourceHeader, Input, &DestHeader, Output, DitherWord);
00468     if (!res)
00469         TRACE( _T("GColour_ConvertBitmap did error %x\n"), GetLastError() );
00470 
00471     return TRUE;
00472 }
00473 
00474 
00475 
00476 /********************************************************************************************
00477 
00478 >   Conv32to8::Conv32to8(UINT32 Width, LPLOGPALETTE Palette, UINT32 DitherType)
00479 
00480     Author:     Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>?
00481     Created:    29/06/96
00482     Purpose:    Constructor
00483 
00484 ********************************************************************************************/
00485 Conv32to8::Conv32to8(UINT32 Width, LPLOGPALETTE Palette, UINT32 DitherType)
00486 {
00487     ERROR3IF(Palette == NULL,"Conv32to8 null palette specified");
00488 
00489     SourceHeader.biPlanes = 1;
00490     SourceHeader.biBitCount = 32;
00491     SourceHeader.biWidth = Width;
00492     SourceHeader.biClrUsed = 0;
00493 
00494     DestHeader.biPlanes = 1;
00495     DestHeader.biBitCount = 8;
00496     DestHeader.biWidth = Width;
00497     DestHeader.biClrUsed = 256;
00498 
00499     DestPalette = Palette;
00500 
00501     // Remember which dithering to use
00502     Dither = DitherType;
00503 
00504     // lets use this palette for the conversion
00505     GDrawContext *GDC = GetConvertContext();
00506 
00507     GDC->SetupBitmap(Width, 16, 8, NULL);
00508 
00509     // This should return a palette plus tell it what dithering we require
00510     // 0 = ordered dither, not 0 for error diffusion or no dithering.
00511 
00512     pcLOGPALETTE lpPalette = GDC->SelectPalette((Dither == XARADITHER_SIMPLE ||
00513                                                  Dither == XARADITHER_ERROR_DIFFUSION ||
00514                                                  Dither == XARADITHER_NONE) ? 1 : 0 );
00515     if (lpPalette == NULL)
00516     {
00517         ENSURE(lpPalette, "Didnt get a palette for export");
00518     }
00519 
00520 
00521     // Graeme (25/9/00) - Removed to prevent a problem with creating a bitmap copy of an
00522     // existing bitmap.
00523 /*
00524     // Added by Craig Hamilton 15/9/00.
00525     // This section of code will replace any flag value with null if it is not a valid value.
00526     INT32 i;
00527 
00528     for(i=0;i<DestPalette->palNumEntries;i++)
00529     {
00530         if(DestPalette->palPalEntry[i].peFlags != NULL && DestPalette->palPalEntry[i].peFlags != PC_EXPLICIT &&
00531             DestPalette->palPalEntry[i].peFlags != PC_NOCOLLAPSE && DestPalette->palPalEntry[i].peFlags != PC_RESERVED)
00532         {
00533             DestPalette->palPalEntry[i].peFlags = NULL;
00534         }
00535     }
00536     // End added.
00537 */
00538 
00539     GDC->InitialiseWithPalette(DestPalette);
00540 }
00541 
00542 Conv32to8::~Conv32to8()
00543 {
00544 }
00545 
00546 BOOL Conv32to8::Convert( LPBYTE Input, LPBYTE Output, UINT32 Height, BOOL FirstStrip )
00547 {
00548     SourceHeader.biHeight = Height;
00549       DestHeader.biHeight = Height;
00550 
00551     //  If we are converting to 8 bit, and the bitmap has less than 256 colours, then
00552     //  it is better to avoid the GDraw conversion function, and do our own instead.
00553 PORTNOTE("other","Removed GRenderOptPalette usage")
00554 #ifndef EXCLUDE_FROM_XARALX
00555     if( GRenderOptPalette::DoGDrawConversion && !GRenderOptPalette::UseOldPalette )
00556     {
00557         // GAT
00558         RGBQUAD aFastPalette[0x100] ;
00559         BYTE aIndex[0x100] ;
00560         UINT32 nEntries = 0 ;
00561 
00562         //  Go through the supplied bitmap strip.
00563         RGBQUAD* InputBytes = (RGBQUAD*)Input ;
00564         BYTE*   OutputBytes = Output ;
00565         UINT32 Width = SourceHeader.biWidth ;
00566         //  Need an offset if the width of the bitmap is not a multiple of 4.
00567         INT32 OffsetValue = Width % 4 ;
00568         if( OffsetValue > 0 )
00569             OffsetValue = 4 - OffsetValue ;
00570 
00571         for( UINT32 j=0 ; j<Height ; j++ )
00572         {
00573             for( UINT32 i=0 ; i<Width ; i++ )
00574             {
00575                 // Get the RGB value for the current pixel.
00576                 // Mask out the alpha channel.
00577                 RGBQUAD rgb = *InputBytes++ ;
00578                 (DWORD&)rgb &= 0xFFFFFF ;
00579                 // Search through the palette to try and find this colour.
00580                 // This code assumes that it will definitely not be more
00581                 // than 256 colours in the palette.
00582                 for( UINT32 k=0 ; k<nEntries ; k++ )
00583                     if( (DWORD&)aFastPalette[k]==(DWORD&)rgb )
00584                     {
00585                         *OutputBytes++ = aIndex[k] ;
00586                         goto done ;     // Use goto for efficiency.
00587                     }
00588                 // Pixel not found so add to tables.
00589                 {
00590                     PALETTEENTRY pe = {rgb.rgbRed,rgb.rgbGreen,rgb.rgbBlue,0} ;
00591                     *OutputBytes++ = aIndex[nEntries] = PaletteManager::FindIndexOfNearestColour( pe, DestPalette ) ;
00592                     aFastPalette[nEntries++] = rgb ;
00593                     ASSERT(nEntries<=256) ;
00594                 }
00595         done:   ;
00596             }
00597             //  After the current row has been done, then apply any 'filler' bytes
00598             //  necessary.
00599             OutputBytes += OffsetValue ;
00600         }
00601         //  Finished now.
00602         return TRUE;
00603     }
00604     else
00605 #endif
00606     {
00607         //  Go here if we have an optimised palette
00608         DWORD DitherWord = Dither;
00609         TRACEUSER( "Andy?", _T("Convert32to8, Strip = %d, dither = %d\n"), FirstStrip, Dither);
00610 
00611         if (Dither == XARADITHER_SIMPLE || Dither == XARADITHER_ERROR_DIFFUSION)
00612         {
00613             // We are using some form of error diffusion ....
00614 
00615             // Set second byte to 255 if this is the First strip,
00616             // so that the error buffer is cleared
00617             DitherWord |= (( FirstStrip ? 0 : 255 ) << 8);
00618         }
00619 
00620         GDrawContext *GDC = GetConvertContext();
00621         const BOOL res = GDC->ConvertBitmap( &SourceHeader, Input, &DestHeader, Output, DitherWord);
00622 
00623         if (!res)
00624             TRACE( _T("GColour_ConvertBitmap did error %x\n"), GetLastError() );
00625 
00626         return TRUE;
00627     }
00628 }
00629 
00630 
00631 
00632 /********************************************************************************************
00633 
00634 >   Conv32to8::Conv32to8(UINT32 Width, LPLOGPALETTE Palette, UINT32 DitherType)
00635 
00636     Author:     Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>?
00637     Created:    29/06/96
00638     Purpose:    Constructor to Convert 32bpp to 4bpp
00639 
00640 ********************************************************************************************/
00641 Conv32to4::Conv32to4( UINT32 Width, LPLOGPALETTE Palette, UINT32 DitherType )
00642 {
00643     ERROR3IF(Palette==NULL,"Conv32to4 null palette specified");
00644 
00645     SourceHeader.biPlanes = 1;
00646     SourceHeader.biBitCount = 32;
00647     SourceHeader.biWidth = Width;
00648     SourceHeader.biClrUsed = 0;
00649 
00650     DestHeader.biPlanes = 1;
00651     DestHeader.biBitCount = 4;
00652     DestHeader.biWidth = Width;
00653     DestHeader.biClrUsed = 16;
00654 
00655     DestPalette = Palette;
00656 
00657     // Remember which dithering to use
00658     Dither = DitherType;
00659 
00660     // lets use this palette for the conversion
00661     GDrawContext *GDC = GetConvertContext();
00662     GDC->SetConversionPalette(DestPalette);
00663 }
00664 
00665 Conv32to4::~Conv32to4()
00666 {
00667 }
00668 
00669 BOOL Conv32to4::Convert( LPBYTE Input, LPBYTE Output, UINT32 Height, BOOL FirstStrip )
00670 {
00671     SourceHeader.biHeight = Height;
00672 
00673     DestHeader.biHeight = Height;
00674 
00675     DWORD DitherWord = Dither;
00676     TRACEUSER( "Andy?", _T("Convert32to4, Strip = %d, dither = %d\n"), FirstStrip, Dither);
00677 
00678     if (Dither == XARADITHER_SIMPLE || Dither == XARADITHER_ERROR_DIFFUSION)
00679     {
00680         // We are using some form of error diffusion ....
00681 
00682         // Set second byte to 255 if this is the First strip,
00683         // so that the error buffer is cleared
00684         DitherWord |= (( FirstStrip ? 0 : 255 ) << 8);
00685     }
00686 
00687     GDrawContext *GDC = GetConvertContext();
00688     const BOOL res = GDC->ConvertBitmap( &SourceHeader, Input, &DestHeader, Output, DitherWord );
00689 
00690     if (!res)
00691         TRACE( _T("GColour_ConvertBitmap did error %x\n"), GetLastError() );
00692 
00693     return TRUE;
00694 }
00695 
00696 
00697 /********************************************************************************************
00698 
00699 >   Conv32to1::Conv32to1( UINT32 Width, LPLOGPALETTE Palette, UINT32 DitherType )
00700 
00701     Author:     Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>?
00702     Created:    29/06/96
00703     Purpose:    Constructor to Convert 32bpp to 1bpp
00704 
00705 ********************************************************************************************/
00706 Conv32to1::Conv32to1( UINT32 Width, LPLOGPALETTE Palette, UINT32 DitherType )
00707 {
00708     ERROR3IF(Palette==NULL,"Conv32to1 null palette specified");
00709 
00710     SourceHeader.biPlanes = 1;
00711     SourceHeader.biBitCount = 32;
00712     SourceHeader.biWidth = Width;
00713     SourceHeader.biClrUsed = 0;
00714 
00715     DestHeader.biPlanes = 1;
00716     DestHeader.biBitCount = 1;
00717     DestHeader.biWidth = Width;
00718     DestHeader.biClrUsed = 2;
00719 
00720     DestPalette = Palette;
00721 
00722     TRACEUSER("Andy?", wxT("Creating Convert32to1, Pal@%x, Entries=%d\n"), DestPalette, DestPalette->palNumEntries);
00723     TRACEUSER("Andy?", wxT("Pal[0] = %dR,%dG,%dB\n"),   DestPalette->palPalEntry[0].peRed,
00724                                                 DestPalette->palPalEntry[0].peGreen,
00725                                                 DestPalette->palPalEntry[0].peBlue);
00726     TRACEUSER("Andy?", wxT("Pal[1] = %dR,%dG,%dB\n"),   DestPalette->palPalEntry[1].peRed,
00727                                                 DestPalette->palPalEntry[1].peGreen,
00728                                                 DestPalette->palPalEntry[1].peBlue);
00729 
00730     // Remember which dithering to use
00731     Dither = DitherType;
00732 
00733     // lets use this palette for the conversion
00734     GDrawContext *GDC = GetConvertContext();
00735     GDC->SetConversionPalette(DestPalette);
00736 }
00737 
00738 Conv32to1::~Conv32to1()
00739 {
00740 }
00741 
00742 BOOL Conv32to1::Convert( LPBYTE Input, LPBYTE Output, UINT32 Height, BOOL FirstStrip )
00743 {
00744     SourceHeader.biHeight = Height;
00745     DestHeader.biHeight = Height;
00746 
00747     DWORD DitherWord = Dither;
00748     TRACEUSER( "Andy?", _T("Convert32to1, Strip = %d, dither = %d\n"), FirstStrip, Dither);
00749 
00750     if (Dither == XARADITHER_SIMPLE || Dither == XARADITHER_ERROR_DIFFUSION)
00751     {
00752         // We are using some form of error diffusion ....
00753 
00754         // Set second byte to 255 if this is the First strip,
00755         // so that the error buffer is cleared
00756         DitherWord |= (( FirstStrip ? 0 : 255 ) << 8);
00757     }
00758 
00759     GDrawContext *GDC = GetConvertContext();
00760     const BOOL res = GDC->ConvertBitmap( &SourceHeader, Input, &DestHeader, Output, DitherWord );
00761     if (!res)
00762         TRACE( _T("GColour_ConvertBitmap did error %x\n"), GetLastError() );
00763 
00764     return TRUE;
00765 }
00766 
00767 
00768 /********************************************************************************************
00769 
00770 >   Conv24to8::Conv24to8(UINT32 Width, LPLOGPALETTE Palette, UINT32 DitherType)
00771 
00772     Author:     Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>?
00773     Created:    29/06/96
00774     Purpose:    Constructor to Special convert 24 to 8 class 
00775 
00776 ********************************************************************************************/
00777 Conv24to8::Conv24to8(UINT32 Width, LPLOGPALETTE Palette, UINT32 DitherType)
00778 {
00779     ERROR3IF(Palette == NULL,"Conv32to8 null palette specified");
00780 
00781     SourceHeader.biPlanes = 1;
00782     SourceHeader.biBitCount = 32;
00783     SourceHeader.biWidth = Width;
00784     SourceHeader.biClrUsed = 0;
00785 
00786     DestHeader.biPlanes = 1;
00787     DestHeader.biBitCount = 8;
00788     DestHeader.biWidth = Width;
00789     DestHeader.biClrUsed = 256;
00790 
00791     DestPalette = Palette;
00792 
00793     // Remember which dithering to use
00794     Dither = DitherType;
00795 
00796     // lets use this palette for the conversion
00797     GDrawContext *GDC = GetConvertContext();
00798 
00799     GDC->SetupBitmap(Width, 16, 8, NULL);
00800 
00801     // This should return a palette plus tell it what dithering we require
00802     // 0 = ordered dither, not 0 for error diffusion or no dithering.
00803 
00804     pcLOGPALETTE lpPalette = GDC->SelectPalette((Dither == XARADITHER_SIMPLE ||
00805                                                             Dither == XARADITHER_ERROR_DIFFUSION ||
00806                                                             Dither == XARADITHER_NONE) ? 1 : 0 );
00807     if (lpPalette == NULL)
00808     {
00809         ENSURE(lpPalette, "Didnt get a palette for export");
00810     }
00811 
00812     GDC->InitialiseWithPalette(DestPalette);
00813 
00814     // GDraw can only cope with 32 bpp data and so we need to convert the data into 32bpp
00815     // before calling GDraw. This is the buffer we use for this
00816     InputBuffer32bpp = NULL;
00817 }
00818 
00819 Conv24to8::~Conv24to8()
00820 {
00821     GRenderRegion::EnsurePalette(-1);
00822     if (InputBuffer32bpp != NULL)
00823         CCFree(InputBuffer32bpp);
00824 }
00825 
00826 BOOL Conv24to8::Convert( LPBYTE Input, LPBYTE Output, UINT32 Height, BOOL FirstStrip )
00827 {
00828     // Assumes first strip will be the largest and so allocates a conversion buffer of this size
00829     
00830     SourceHeader.biHeight = Height;
00831 
00832     DestHeader.biHeight = Height;
00833 
00834     INT32 Width24bpp = DIBUtil::ScanlineSize(SourceHeader.biWidth, 24);
00835     INT32 Width32bpp = DIBUtil::ScanlineSize(SourceHeader.biWidth, 32);
00836     if (InputBuffer32bpp == NULL)
00837     {
00838         // If we haven't done so already then allocate ourselves our conversion buffer
00839         InputBuffer32bpp = (LPBYTE)CCMalloc(Width32bpp * Height);
00840         if (InputBuffer32bpp == NULL)
00841             return FALSE;
00842     }
00843 
00844     // Copy the data across from the source 24bpp buffer into the 32bpp buffer
00845     INT32 PixelWidth = SourceHeader.biWidth;
00846     LPBYTE InputBits = Input;
00847     LPBYTE OutputBits = InputBuffer32bpp;
00848     // Convert it a pixel line at a time
00849     for (UINT32 i = 0; i < Height; i++)
00850     {
00851         Convert24to32(PixelWidth, InputBits, OutputBits);
00852         InputBits += Width24bpp;
00853         OutputBits += Width32bpp;
00854     }
00855 
00856     DWORD DitherWord = Dither;
00857     if (FirstStrip)
00858         TRACEUSER( "Neville", _T("Convert24to8, Strip = %d, dither = %d\n"), FirstStrip, Dither);
00859 
00860     if (Dither == XARADITHER_SIMPLE || Dither == XARADITHER_ERROR_DIFFUSION)
00861     {
00862         // We are using some form of error diffusion ....
00863 
00864         // Set second byte to 255 if this is the First strip,
00865         // so that the error buffer is cleared
00866         DitherWord |= (( FirstStrip ? 0 : 255 ) << 8);
00867     }
00868 
00869     GDrawContext *GDC = GetConvertContext();
00870     const BOOL res = GDC->ConvertBitmap( &SourceHeader, InputBuffer32bpp, &DestHeader, Output, DitherWord);
00871     if (!res)
00872         TRACE( _T("GColour_ConvertBitmap did error %x\n"), GetLastError() );
00873 
00874     return TRUE;
00875 }
00876 
00877 void Conv24to8::Convert24to32( INT32 PixelWidth, LPBYTE InputBits, LPBYTE OutputBits )
00878 {
00879     // Convert a scanline from 24 to 32 bpp so that GDraw can work with it
00880     // source form is B,G,R
00881     // dest is B,G,R,spare
00882     // Note: if not little-endian, is this still true?
00883     while (PixelWidth--)
00884     {
00885         OutputBits[0] = InputBits[0];
00886         OutputBits[1] = InputBits[1];
00887         OutputBits[2] = InputBits[2];
00888         OutputBits[3] = 0xFF;
00889         OutputBits += 4;
00890         InputBits  += 3;
00891     }
00892 }
00893 
00894 
00895 /********************************************************************************************
00896 
00897 >   Conv8to32::Conv8to32( LPBITMAPINFO pSourceHeader )
00898 
00899     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00900     Created:    07/11/96
00901     Purpose:    Constructor to convert 8 to 32
00902 
00903 ********************************************************************************************/
00904 Conv8to32::Conv8to32( LPBITMAPINFO pSourceHeader )
00905 {
00906     ERROR3IF(pSourceHeader->bmiHeader.biBitCount != 8,"Conv8to32 not 8bpp");
00907 
00908     m_pSourceHeader = pSourceHeader;
00909 }
00910 
00911 
00912 
00913 /********************************************************************************************
00914 
00915 >   BOOL Conv8to32::Convert( LPBYTE pInputBits, LPBYTE pOutputBits, UINT32 Height, BOOL FirstStrip )
00916 
00917     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00918     Created:    07/11/96
00919     Purpose:    Sub-optimal conversion routine
00920 
00921 ********************************************************************************************/
00922 BOOL Conv8to32::Convert( LPBYTE pInputBits, LPBYTE pOutputBits, UINT32 Height, BOOL FirstStrip )
00923 {
00924     ERROR3IF(pInputBits == NULL || pOutputBits == NULL, "Conv8to32: NULL Inputs");
00925 
00926     const RGBQUAD* pPalette = m_pSourceHeader->bmiColors;
00927     const UINT32 Width = m_pSourceHeader->bmiHeader.biWidth;
00928 
00929     RGBQUAD* pCurrentOutput = (RGBQUAD*)pOutputBits;
00930     LPBYTE pCurrentInput    = pInputBits;
00931 
00932     while (Height--)
00933     {
00934         UINT32 CurrentX = Width;
00935         while (CurrentX--)
00936         {
00937             RGBQUAD PaletteEntry = pPalette[*pCurrentInput];
00938             PaletteEntry.rgbReserved = 0xFF;
00939 
00940             *pCurrentOutput = PaletteEntry;
00941 
00942             ++pCurrentOutput;
00943             ++pCurrentInput;
00944         }
00945     }
00946 
00947     return TRUE;
00948 }
00949 
00950 
00951 /********************************************************************************************
00952 
00953 >   Conv24to32::Conv24to32( LPBITMAPINFO pSourceHeader )
00954 
00955     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00956     Created:    07/11/96
00957     Purpose:    Constructor to convert 24 to 32
00958 
00959 ********************************************************************************************/
00960 Conv24to32::Conv24to32( LPBITMAPINFO pSourceHeader )
00961 {
00962     ERROR3IF(pSourceHeader->bmiHeader.biBitCount != 24,"Conv24to32 not 24bpp");
00963 
00964     m_pSourceHeader = pSourceHeader;
00965 }
00966 
00967 
00968 
00969 /********************************************************************************************
00970 
00971 >   BOOL Conv24to32::Convert(   LPBYTE pInputBits, LPBYTE pOutputBits, UINT32 Height, 
00972                                 BOOL FirstStrip )
00973     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00974     Created:    07/11/96
00975     Purpose:    Sub-optimal conversion routine
00976 
00977 ********************************************************************************************/
00978 BOOL Conv24to32::Convert( LPBYTE pInputBits, LPBYTE pOutputBits, UINT32 Height, BOOL FirstStrip )
00979 {
00980     ERROR3IF(pInputBits == NULL || pOutputBits == NULL, "Conv24to32: NULL Inputs");
00981 
00982     // Convert a scanline from 24 to 32 bpp so that GDraw can work with it
00983     // source form is B,G,R
00984     // dest is B,G,R,spare
00985     // Note: if not little-endian, is this still true?
00986     const UINT32 Width = m_pSourceHeader->bmiHeader.biWidth;
00987 
00988     for (UINT32 CurrentY = Height; CurrentY != 0; --CurrentY)
00989     {
00990         for (UINT32 CurrentX = Width; CurrentX != 0; --CurrentX)
00991         {
00992             pOutputBits[0] = pInputBits[0];
00993             pOutputBits[1] = pInputBits[1];
00994             pOutputBits[2] = pInputBits[2];
00995             pOutputBits[3] = 0xFF;
00996             pOutputBits += 4;
00997             pInputBits  += 3;
00998         }
00999     }
01000 
01001     return TRUE;
01002 }

Generated on Sat Nov 10 03:48:20 2007 for Camelot by  doxygen 1.4.4