00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 #include "camtypes.h"
00105
00106 #include "cartprov.h"
00107 #include "oilbitmap.h"
00108
00109
00110
00111
00112 #include "camelot.h"
00113 #include "bitmpinf.h"
00114
00115 #include "nativeps.h"
00116 #include "saveeps.h"
00117 #include "cameleps.h"
00118
00119
00120
00121
00122
00123
00124
00125 #include "prdlgctl.h"
00126 #include "printctl.h"
00127
00128
00129 #include "colcontx.h"
00130 #include "colormgr.h"
00131 #include "colplate.h"
00132
00133 #include "bitfilt.h"
00134
00135
00136
00137
00138
00139
00140
00141 CC_IMPLEMENT_DYNAMIC( CWxBitmap, OILBitmap )
00142
00143
00144 #define new CAM_DEBUG_NEW
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 BOOL OILBitmap::Init()
00163 {
00164 static String_256 FillBitmapName;
00165
00166 CamResource BitmapResource;
00167 BOOL ShouldDeleteFileObject=TRUE;
00168
00169 CCLexFile *File = NULL;
00170
00171 if (!Camelot.DeclareSection( wxT("Attributes"), 10))
00172 return TRUE;
00173
00174 Camelot.DeclarePref( NULL, wxT("FillBitmap"), &FillBitmapName );
00175
00176 if (!FillBitmapName.IsEmpty())
00177 {
00178
00179 CCDiskFile *DiskFile = new CCDiskFile(16384);
00180
00181
00182 if (DiskFile)
00183 {
00184 if ( DiskFile->IsInited() )
00185 {
00186 PathName WhichFile( FillBitmapName );
00187
00188
00189 if ( WhichFile.IsValid(FillBitmapName) )
00190 {
00191 if (!DiskFile->open( WhichFile, ios::in | ios::binary ))
00192 {
00193 delete DiskFile;
00194 DiskFile = NULL;
00195 }
00196 }
00197 }
00198 else
00199 {
00200 delete DiskFile;
00201 DiskFile = NULL;
00202 }
00203
00204 if (DiskFile==NULL)
00205 InformError();
00206 else
00207 File = DiskFile;
00208 }
00209 }
00210
00211 BOOL ReadHeader = TRUE;
00212
00213 if( File == NULL )
00214 {
00215 File = BitmapResource.Open(_R(IDB_DEFAULTFILL));
00216 ShouldDeleteFileObject=FALSE;
00217 }
00218
00219
00220
00221 if (File)
00222 {
00223 LPBITMAPINFO Info;
00224 LPBYTE Bytes;
00225
00226 File->SetReportErrors(FALSE);
00227
00228 if ( DIBUtil::ReadFromFile( File, &Info, &Bytes, ReadHeader ) )
00229 {
00230
00231 OILBitmap::Default = new CWxBitmap( Info, Bytes );
00232
00233 if (!OILBitmap::Default)
00234 FreeDIB( Info, Bytes );
00235 else
00236 {
00237 Info->bmiHeader.biXPelsPerMeter = 3780;
00238 Info->bmiHeader.biYPelsPerMeter = 3780;
00239
00240 String_256 Str = _R(IDS_WBITMAP_DEFAULT);
00241 OILBitmap::Default->SetName(Str);
00242 OILBitmap::Attach( OILBitmap::Default );
00243 }
00244 }
00245 else
00246 InformError();
00247
00248
00249 if (File->isOpen())
00250 File->close();
00251
00252
00253 if (ShouldDeleteFileObject) delete File;
00254 }
00255
00256 return TRUE;
00257 }
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 void OILBitmap::Deinit()
00271 {
00272 delete OILBitmap::Default;
00273 OILBitmap::Default = NULL;
00274
00275
00276 }
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 OILBitmap *OILBitmap::Create()
00292 {
00293
00294 return new CWxBitmap;
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 OILBitmap *OILBitmap::Create( UINT32 Width, UINT32 Height, UINT32 Depth, UINT32 dpi )
00314 {
00315 LPBITMAPINFO bmInfo;
00316 LPBYTE bmBytes;
00317
00318 bmInfo = AllocDIB( Width, Height, Depth, &bmBytes );
00319 if (bmInfo)
00320 {
00321
00322 double xppm = ((double)dpi * 10000.0)/254.0;
00323 bmInfo->bmiHeader.biXPelsPerMeter = (INT32)(xppm + 0.5);
00324 bmInfo->bmiHeader.biYPelsPerMeter = bmInfo->bmiHeader.biXPelsPerMeter;
00325 CWxBitmap *WinBM = new CWxBitmap( bmInfo, bmBytes );
00326 if (WinBM)
00327 return WinBM;
00328 else
00329 FreeDIB( bmInfo, bmBytes );
00330 }
00331 return NULL;
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 CWxBitmap::CWxBitmap()
00348 {
00349 BMInfo = NULL;
00350 BMBytes = NULL;
00351
00352
00353 ScanLineByteWidth = 0;
00354 BitmapSize = 0;
00355
00356 CacheGeometry();
00357 }
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 CWxBitmap::CWxBitmap(LPBITMAPINFO Info, LPBYTE Bytes)
00372 {
00373 BMInfo = Info;
00374 BMBytes = Bytes;
00375
00376 ScanLineByteWidth = 0;
00377 BitmapSize = 0;
00378
00379 CacheGeometry();
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394 CWxBitmap::~CWxBitmap()
00395 {
00396 if (!HasBeenDeleted())
00397 {
00398 if (BMInfo != NULL && BMBytes != NULL)
00399 {
00400 FreeDIB( BMInfo, BMBytes );
00401 BMInfo = NULL;
00402 BMBytes = NULL;
00403 }
00404 }
00405
00406 if (m_pGreyscaleTable)
00407 delete m_pGreyscaleTable;
00408 }
00409
00410
00411
00412 #define MILLIS_PER_METRE 2834646L
00413
00414
00415
00416
00417 #define DEFAULT_PIXEL_SIZE 3780
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452 BOOL CWxBitmap::GetInfo(BitmapInfo *Info, RenderRegion *pRegion)
00453 {
00454 ERROR3IF(Info == NULL, "Illegal NULL param");
00455 RebuildXPEBitmap();
00456
00457 if (BMInfo && BMBytes && !m_bNeedsXPERebuild)
00458 {
00459 Info->PixelWidth = GetWidth();
00460 Info->PixelHeight = GetHeight();
00461 Info->PixelDepth = GetBPP(pRegion);
00462 Info->NumPaletteEntries = GetNumPaletteEntries();
00463
00464 INT32 PelW = BMInfo->bmiHeader.biXPelsPerMeter;
00465 if (PelW==0)
00466 PelW = DEFAULT_PIXEL_SIZE;
00467
00468 INT32 PelH = BMInfo->bmiHeader.biYPelsPerMeter;
00469 if (PelH==0)
00470 PelH = DEFAULT_PIXEL_SIZE;
00471
00472 if ( (PelW<0) || (PelH<0) )
00473 {
00474 ERROR3("Bad pixel size");
00475 return FALSE;
00476 }
00477
00478
00479
00480
00481
00482 if (PelW == 3780 && PelH == 3780)
00483 {
00484 Info->RecommendedWidth = Info->PixelWidth * 750;
00485 Info->RecommendedHeight = Info->PixelHeight * 750;
00486 }
00487
00488
00489 else
00490 {
00491
00492
00493
00494
00495 double RecWidth = ((double)Info->PixelWidth * M_MP_VAL)/(double)PelW;
00496 double RecHeight = ((double)Info->PixelHeight * M_MP_VAL)/(double)PelH;
00497 Info->RecommendedWidth = (INT32)(RecWidth + 0.5);
00498 Info->RecommendedHeight= (INT32)(RecHeight + 0.5);
00499 }
00500
00501
00502
00503 Info->MemoryUsed = BMInfo->bmiHeader.biSizeImage;
00504
00505 return TRUE;
00506 }
00507
00508 return FALSE;
00509 }
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527 UINT32 CWxBitmap::GetWidth()
00528 {
00529 RebuildXPEBitmap();
00530 if (BMInfo == NULL)
00531 return(0);
00532
00533 return(BMInfo->bmiHeader.biWidth);
00534 }
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 UINT32 CWxBitmap::GetHeight()
00553 {
00554 RebuildXPEBitmap();
00555 if (BMInfo == NULL)
00556 return(0);
00557
00558 return(BMInfo->bmiHeader.biHeight);
00559 }
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573 UINT32 CWxBitmap::GetHorizontalDPI()
00574 {
00575 RebuildXPEBitmap();
00576 if (BMInfo == NULL)
00577 return 96;
00578
00579 INT32 PelW = BMInfo->bmiHeader.biXPelsPerMeter;
00580 if (PelW <= 0)
00581 PelW = DEFAULT_PIXEL_SIZE;
00582
00583 UINT32 dpi = (UINT32)((((double)PelW * 254.0)/10000.0) + 0.5);
00584 return dpi;
00585 }
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599 UINT32 CWxBitmap::GetVerticalDPI()
00600 {
00601 RebuildXPEBitmap();
00602 if (BMInfo == NULL)
00603 return(0);
00604
00605 INT32 PelH = BMInfo->bmiHeader.biYPelsPerMeter;
00606 if (PelH <= 0)
00607 PelH = DEFAULT_PIXEL_SIZE;
00608
00609 UINT32 dpi = (UINT32)((((double)PelH * 254.0)/10000.0) + 0.5);
00610 return dpi;
00611 }
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637 UINT32 CWxBitmap::GetBPP(RenderRegion *pRegion)
00638 {
00639 RebuildXPEBitmap();
00640
00641
00642
00643 if (BMInfo == NULL)
00644 return 0;
00645
00646 return BMInfo->bmiHeader.biBitCount;
00647 }
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660 BOOL CWxBitmap::SetTransparencyIndex(INT32 Index)
00661 {
00662 RebuildXPEBitmap();
00663 ERROR3IF(BMInfo == NULL, "SetTransparencyIndex called when BMInfo is NULL");
00664 if (BMInfo == NULL)
00665 return FALSE;
00666
00667 INT32 NumCols = 0;
00668
00669 switch (GetBPP())
00670 {
00671 case 1:
00672 NumCols = 2;
00673 break;
00674
00675 case 4:
00676 NumCols = 16;
00677 break;
00678
00679 case 8:
00680 NumCols = 256;
00681 break;
00682
00683 default:
00684 ERROR3("Bad colour depth in SetTransparencyIndex");
00685 break;
00686 }
00687
00688 RGBQUAD* pCols = BMInfo->bmiColors;
00689
00690
00691 for (INT32 i=0; i<NumCols; i++)
00692 {
00693 if (i == Index)
00694 pCols[i].rgbReserved = 0xFF;
00695 else
00696 pCols[i].rgbReserved = 0;
00697 }
00698
00699 return TRUE;
00700 }
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713 BOOL CWxBitmap::GetTransparencyIndex(INT32* pIndex)
00714 {
00715 ERROR3IF(pIndex == NULL, "GetTransparencyIndex called with NULL index pointer");
00716 if (pIndex == NULL)
00717 return FALSE;
00718
00719 RebuildXPEBitmap();
00720 ERROR3IF(BMInfo == NULL, "GetTransparencyIndex called when BMInfo is NULL");
00721 if (BMInfo == NULL)
00722 return FALSE;
00723
00724 INT32 NumCols = 0;
00725
00726 switch (GetBPP())
00727 {
00728 case 1:
00729 NumCols = 2;
00730 break;
00731
00732 case 4:
00733 NumCols = 16;
00734 break;
00735
00736 case 8:
00737 NumCols = 256;
00738 break;
00739
00740 default:
00741 ERROR3("Bad colour depth in GetTransparencyIndex");
00742 break;
00743 }
00744
00745 RGBQUAD* pCols = BMInfo->bmiColors;
00746
00747 *pIndex = -1;
00748
00749
00750 for (INT32 i=0; i<NumCols; i++)
00751 {
00752 if (pCols[i].rgbReserved == 0xFF)
00753 {
00754 *pIndex = i;
00755
00756 }
00757 }
00758
00759 return ((*pIndex) >= 0);
00760 }
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774 BOOL CWxBitmap::IsTransparent()
00775 {
00776 RebuildXPEBitmap();
00777 ERROR3IF(BMInfo == NULL, "IsTransparent called when BMInfo is NULL");
00778
00779 if (BMInfo == NULL)
00780 return(FALSE);
00781
00782 if (GetBPP() <= 8)
00783 {
00784 INT32 TranspIndex;
00785
00786
00787 if (!GetTransparencyIndex(&TranspIndex))
00788 return(FALSE);
00789
00790 switch (GetBPP())
00791 {
00792 case 1:
00793 {
00794 BYTE* pBits = (BYTE*)(GetBitmapBits());
00795 UINT32 FullBytes = GetWidth() >> 3;
00796 UINT32 Height = GetHeight();
00797 UINT32 ScanLen = GetScanlineSize();
00798 BYTE Mask = 0xFF >> (7-(GetWidth() - (FullBytes << 3)));
00799 if (TranspIndex == 0)
00800 {
00801 for (UINT32 y = 0; y < Height; y++)
00802 {
00803 UINT32 x;
00804 for (x = 0; x < FullBytes; x++)
00805 {
00806 if (pBits[x] != 0xFF)
00807 return(TRUE);
00808 }
00809 if (Mask)
00810 {
00811 if ((pBits[x] & Mask) != Mask)
00812 return(TRUE);
00813 }
00814 pBits += ScanLen;
00815 }
00816 }
00817 else
00818 {
00819 for (UINT32 y = 0; y < Height; y++)
00820 {
00821 UINT32 x;
00822 for( x = 0; x < FullBytes; x++)
00823 {
00824 if (pBits[x] != 0x00)
00825 return(TRUE);
00826 }
00827 if (Mask)
00828 {
00829 if ((pBits[x] & Mask) != 0x00)
00830 return(TRUE);
00831 }
00832 pBits += ScanLen;
00833 }
00834 }
00835 }
00836 break;
00837
00838 case 4:
00839 {
00840 BYTE* pBits = (BYTE*)(GetBitmapBits());
00841 UINT32 Width = GetWidth();
00842 UINT32 ByteWidth = (Width + 1) >> 1;
00843 UINT32 Height = GetHeight();
00844 UINT32 ScanLen = GetScanlineSize();
00845 INT32 TranspIndexHigh = TranspIndex << 4;
00846 for (UINT32 y = 0; y < Height; y++)
00847 {
00848 UINT32 x;
00849 for( x = 0; x < ByteWidth; x++)
00850 {
00851 if ((pBits[x] & 0x0F) == TranspIndex)
00852 return(TRUE);
00853 if ((pBits[x] & 0xF0) == TranspIndexHigh)
00854 return(TRUE);
00855 }
00856 if (Width % 2 == 1)
00857 {
00858 if ((pBits[x] & 0x0F) == TranspIndex)
00859 return(TRUE);
00860 }
00861 pBits += ScanLen;
00862 }
00863 }
00864 break;
00865
00866 case 8:
00867 {
00868 BYTE* pBits = (BYTE*)(GetBitmapBits());
00869 UINT32 Width = GetWidth();
00870 UINT32 Height = GetHeight();
00871 UINT32 ScanLen = GetScanlineSize();
00872 for (UINT32 y = 0; y < Height; y++)
00873 {
00874 for (UINT32 x = 0; x < Width; x++)
00875 {
00876 if (pBits[x] == TranspIndex)
00877 return(TRUE);
00878 }
00879 pBits += ScanLen;
00880 }
00881 }
00882 break;
00883
00884 default:
00885 ERROR3("Bad colour depth in IsTransparent");
00886 break;
00887 }
00888 }
00889 else if (GetBPP() == 32)
00890 {
00891
00892 DWORD* pBits = (DWORD*)(GetBitmapBits());
00893 UINT32 Width = GetWidth();
00894 UINT32 Height = GetHeight();
00895 DWORD* pEnd = pBits + (Width * Height);
00896 while (pBits < pEnd)
00897 {
00898 if (*pBits && 0xFF000000)
00899 return(TRUE);
00900 pBits++;
00901 }
00902 }
00903
00904 return(FALSE);
00905 }
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919 INT32 CWxBitmap::GetRecommendedWidth()
00920 {
00921 RebuildXPEBitmap();
00922 const UINT32 Width = BMInfo->bmiHeader.biWidth;
00923
00924 INT32 PelW = BMInfo->bmiHeader.biXPelsPerMeter;
00925 if (PelW==0)
00926 PelW = DEFAULT_PIXEL_SIZE;
00927
00928 if ( (PelW<0) )
00929 {
00930 ERROR3IF(TRUE, "Bad pixel size");
00931 return 0;
00932 }
00933
00934 double RecWidth = ((double)Width * M_MP_VAL)/(double)PelW;
00935
00936 return (INT32)(RecWidth + 0.5);
00937 }
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950 INT32 CWxBitmap::GetRecommendedHeight()
00951 {
00952 RebuildXPEBitmap();
00953 const UINT32 Height = BMInfo->bmiHeader.biHeight;
00954
00955 INT32 PelH = BMInfo->bmiHeader.biYPelsPerMeter;
00956 if (PelH==0)
00957 PelH = DEFAULT_PIXEL_SIZE;
00958
00959 if ( (PelH<0) )
00960 {
00961 ERROR3IF(TRUE, "Bad pixel size");
00962 return FALSE;
00963 }
00964
00965 double RecHeight = ((double)Height * M_MP_VAL)/(double)PelH;
00966
00967 return (INT32)(RecHeight + 0.5);
00968 }
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981 void CWxBitmap::SetRecommendedWidth(INT32 NewWidth)
00982 {
00983 RebuildXPEBitmap();
00984 if (BMInfo)
00985 {
00986 double PelW = DEFAULT_PIXEL_SIZE;
00987
00988 if (NewWidth > 0)
00989 {
00990 const UINT32 Width = BMInfo->bmiHeader.biWidth;
00991 PelW = ((double)Width * M_MP_VAL)/(double)NewWidth;
00992 }
00993
00994 BMInfo->bmiHeader.biXPelsPerMeter = (INT32)(PelW + 0.5);
00995 }
00996 }
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009 void CWxBitmap::SetRecommendedHeight(INT32 NewHeight)
01010 {
01011 RebuildXPEBitmap();
01012 if (BMInfo)
01013 {
01014 double PelH = DEFAULT_PIXEL_SIZE;
01015
01016 if (NewHeight > 0)
01017 {
01018 const UINT32 Height = BMInfo->bmiHeader.biHeight;
01019 PelH = ((double)Height * M_MP_VAL)/(double)NewHeight;
01020 }
01021
01022 BMInfo->bmiHeader.biYPelsPerMeter = (INT32)(PelH + 0.5);
01023 }
01024 }
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038 OILBitmap* CWxBitmap::MakeCopy()
01039 {
01040 RebuildXPEBitmap();
01041
01042 if (BMInfo == NULL || BMBytes == NULL)
01043 {
01044 ERROR3("This bitmap has no bits or info to copy!");
01045 return NULL;
01046 }
01047
01048 LPBYTE pNewBits = NULL;
01049 LPBITMAPINFO pNewInfo = NULL;
01050
01051
01052 DIBUtil::CopyEntireBitmap(BMInfo, BMBytes, &pNewInfo, &pNewBits);
01053
01054 if (pNewInfo == NULL || pNewBits == NULL)
01055 {
01056 ERROR3("Failed to allocate bitmap structures");
01057 return NULL;
01058 }
01059
01060 CWxBitmap* pNewBitmap = new CWxBitmap(pNewInfo, pNewBits);
01061
01062 if (pNewBitmap == NULL)
01063 {
01064 ERROR3("Failed to allocate new CWxBitmap");
01065 FreeDIB(pNewInfo, pNewBits);
01066 }
01067 return pNewBitmap;
01068 }
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087 UINT32 CWxBitmap::GetNumPaletteEntries()
01088 {
01089 RebuildXPEBitmap();
01090 if (BMInfo != NULL && BMInfo->bmiHeader.biBitCount <= 8)
01091 {
01092
01093 return(BMInfo->bmiHeader.biClrUsed);
01094 }
01095
01096
01097 return(0);
01098 }
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122 UINT32 CWxBitmap::GetScanlineSize()
01123 {
01124 RebuildXPEBitmap();
01125 if (BMInfo == NULL)
01126 return(0);
01127
01128 return(DIBUtil::ScanlineSize(GetWidth(), GetBPP()));
01129 }
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150 #define CMXREDUCEBPPBUFFERSIZE (1024 * 4) // in pixels
01151
01152 BOOL CWxBitmap::ExportBitmap(RenderRegion *pRegion)
01153 {
01154 #if !defined(EXCLUDE_FROM_RALPH)
01155 RebuildXPEBitmap();
01156
01157 if (pRegion->IsKindOf(CC_RUNTIME_CLASS(CamelotEPSRenderRegion)))
01158 {
01159
01160 if (!ExportBitmapPalette(pRegion))
01161
01162 return FALSE;
01163
01164 if (!ExportBitmapData(pRegion))
01165
01166 return FALSE;
01167 }
01168 PORTNOTE("cmx", "Disabled CMXRenderRegion")
01169 #ifndef EXCLUDE_FROM_XARALX
01170 else if (pRegion->IsKindOf(CC_RUNTIME_CLASS(CMXRenderRegion)))
01171 {
01172
01173 CMXExportDC *pDC = (CMXExportDC *) pRegion->GetRenderDC();
01174
01175
01176 if(!pDC->StartRIFFList(cmxRIFFLIST_ImageDesc))
01177 return FALSE;
01178
01179
01180 if(!pDC->StartSection(CMXExportDC::CMXSECTION_IMAGINFO))
01181 return FALSE;
01182
01183
01184 if(!pDC->StartTag(cmxTAG_DescrSection_Image_ImageInfo))
01185 return FALSE;
01186
01187
01188 BOOL NoPal = FALSE;
01189 if(BMInfo->bmiHeader.biBitCount >= 24)
01190 NoPal = TRUE;
01191
01192
01193
01194 BOOL eBitmapSize = BitmapSize;
01195 BOOL Is32Bit = FALSE;
01196 if(BMInfo->bmiHeader.biBitCount == 32)
01197 {
01198 Is32Bit = TRUE;
01199
01200
01201 eBitmapSize = GetWidth() * 3;
01202 if((eBitmapSize & 0x3) != 0)
01203 eBitmapSize = (eBitmapSize + 4) & ~0x3;
01204 eBitmapSize *= GetHeight();
01205 }
01206
01207
01208 cmxImageInfo ii;
01209 cmxImageHeader ih;
01210 cmxRIMAGEHeader rh;
01211 cmxRIMAGEPaletteHeader ph;
01212
01213 DWORD BitmapHeaderSize = sizeof(rh) + (NoPal?0:(sizeof(ph) + sizeof(cmxRIMAGEPaletteEntry) * BMInfo->bmiHeader.biClrUsed));
01214
01215 ii.Type = cmxIMAGETYPE_RIMAGE;
01216 ii.Compression = 1;
01217 ii.Size = sizeof(ih) + BitmapHeaderSize + eBitmapSize;
01218 ii.CompressedSize = sizeof(ih) + BitmapHeaderSize + eBitmapSize;
01219
01220 pDC->WriteData(&ii, sizeof(ii));
01221
01222
01223 if(!pDC->EndTag() || !pDC->WriteMinEndTag())
01224 return FALSE;
01225
01226
01227 if(!pDC->EndSection())
01228 return FALSE;
01229
01230
01231 if(!pDC->StartSection(CMXExportDC::CMXSECTION_IMAGDATA))
01232 return FALSE;
01233
01234
01235
01236 CMXFutureLength TagLen;
01237 if(pDC->IsThirtyTwoBit())
01238 {
01239 pDC->WriteByte(cmxTAG_DescrSection_Image_ImageData);
01240 DWORD len = 0;
01241 pDC->WriteData(&len, sizeof(len));
01242 TagLen.Init(pDC, - (INT32)sizeof(len), sizeof(len));
01243 TagLen.SetLengthStartPos(pDC, - (INT32)(sizeof(len) + sizeof(BYTE)));
01244 }
01245
01246
01247 ih.ImageType[0] = 'R';
01248 ih.ImageType[1] = 'I';
01249 ih.Size = eBitmapSize + sizeof(ih) + BitmapHeaderSize;
01250 ih.Reserved[0] = 0;
01251 ih.Reserved[1] = 0;
01252 ih.OffsetToPixels = sizeof(ih) + BitmapHeaderSize;
01253
01254 if(!pDC->WriteData(&ih, sizeof(ih)))
01255 return FALSE;
01256
01257
01258 rh.Type = NoPal?cmxR_IMG_RGB:cmxR_IMG_PAL;
01259 rh.ComprType = 1;
01260 rh.Width = GetWidth();
01261 rh.Height = GetHeight();
01262 rh.Planes = 1;
01263 rh.BitsPerPlane = NoPal?24:BMInfo->bmiHeader.biBitCount;
01264 rh.BytesPerLine = (rh.Width * rh.BitsPerPlane) / 8;
01265 if((rh.BytesPerLine & 0x3) != 0)
01266 rh.BytesPerLine = (rh.BytesPerLine + 4) & ~0x3;
01267 rh.BufSize = eBitmapSize;
01268 rh.ComprBufSize = 0;
01269 rh.XPelsPerKM = rh.YPelsPerKM = 0x3d400;
01270 rh.PaletteOffset = NoPal?0:sizeof(rh);
01271 rh.DataOffset = BitmapHeaderSize;
01272 rh.StartBufOffset = 0;
01273 rh.AlphaOffset = 0;
01274 rh.MaskOffset = 0;
01275
01276 if(rh.BitsPerPlane == 4 && !pDC->IsThirtyTwoBit())
01277 {
01278 rh.Type = cmxR_IMG_PAL4;
01279 }
01280
01281
01282 if(!pDC->WriteData(&rh, sizeof(rh)))
01283 return FALSE;
01284
01285 if(!NoPal)
01286 {
01287
01288 CMXRenderRegion *pR = (CMXRenderRegion *)pRegion;
01289 RGBQUAD *pPal = pR->GetAreExportingContoneBitmap()
01290 ?m_pContonePalette:BMInfo->bmiColors;
01291
01292
01293 ph.Type = cmxR_PALETTE_RGB;
01294 ph.NumEntries = (WORD)BMInfo->bmiHeader.biClrUsed;
01295 if(!pDC->WriteData(&ph, sizeof(ph)))
01296 return FALSE;
01297
01298 for(DWORD l = 0; l < BMInfo->bmiHeader.biClrUsed; l++)
01299 {
01300 ERROR3IF(sizeof(cmxRIMAGEPaletteEntry) != 3, "wrong size of entry");
01301 cmxRIMAGEPaletteEntry pi;
01302 pi.b = pPal[l].rgbBlue;
01303 pi.g = pPal[l].rgbGreen;
01304 pi.r = pPal[l].rgbRed;
01305 if(!pDC->WriteData(&pi, sizeof(pi)))
01306 return FALSE;
01307 }
01308 }
01309
01310
01311
01312
01313 if(!Is32Bit)
01314 {
01315
01316 if(!pDC->WriteData(BMBytes, BitmapSize))
01317 return FALSE;
01318 }
01319 else
01320 {
01321
01322
01323 BYTE Buffer[CMXREDUCEBPPBUFFERSIZE * 3];
01324 INT32 BufLoc = 0;
01325 INT32 PixelsToGo = GetWidth() * GetHeight();
01326 INT32 PixelsToGoInLine = GetWidth();
01327 BYTE *Pixels = (BYTE *)BMBytes;
01328 INT32 Bytes = 0;
01329
01330 while(PixelsToGo > 0)
01331 {
01332
01333 Buffer[BufLoc++] = *(Pixels++);
01334 Buffer[BufLoc++] = *(Pixels++);
01335 Buffer[BufLoc++] = *(Pixels++);
01336 Pixels++;
01337 Bytes += 3;
01338
01339
01340 PixelsToGo--;
01341 PixelsToGoInLine--;
01342
01343
01344 if(PixelsToGoInLine <= 0)
01345 {
01346
01347 if((Bytes & 0x3) != 0)
01348 {
01349 INT32 Need = ((Bytes + 4) & ~0x3) - Bytes;
01350 for(INT32 l = 0; l < Need; l++)
01351 {
01352 Buffer[BufLoc++] = 0;
01353 Bytes++;
01354 }
01355 }
01356
01357 PixelsToGoInLine = GetWidth();
01358 }
01359
01360
01361 if(BufLoc >= ((CMXREDUCEBPPBUFFERSIZE * 3) - 8))
01362 {
01363
01364 pDC->WriteData(Buffer, BufLoc);
01365
01366
01367 BufLoc = 0;
01368 }
01369 }
01370
01371
01372 pDC->WriteData(Buffer, BufLoc);
01373 }
01374
01375
01376 if(pDC->IsThirtyTwoBit())
01377 TagLen.Write(pDC);
01378
01379
01380 if(!pDC->WriteMinEndTag())
01381 return FALSE;
01382
01383
01384 if(!pDC->EndSection())
01385 return FALSE;
01386
01387
01388 if(!pDC->EndRIFFList())
01389 return FALSE;
01390
01391 return TRUE;
01392 }
01393 #endif
01394 #endif
01395
01396 return TRUE;
01397 }
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429 BOOL CWxBitmap::ExportBitmapPaletteInternal(RenderRegion *pRegion, INT32 NumColours, RGBQUAD *pSrcCLUT)
01430 {
01431 #if !defined(EXCLUDE_FROM_RALPH)
01432 RebuildXPEBitmap();
01433
01434 ERROR3IF((BMInfo->bmiHeader.biBitCount != 1) &&
01435 (BMInfo->bmiHeader.biBitCount != 4) &&
01436 (BMInfo->bmiHeader.biBitCount != 8) &&
01437 (BMInfo->bmiHeader.biBitCount != 24) &&
01438 (BMInfo->bmiHeader.biBitCount != 32), "Bad bitmap depth in ExportBitmap!");
01439
01440 ERROR3IF(pRegion == NULL || pSrcCLUT == NULL, "Illegal NULL params");
01441
01442 const INT32 ClutSize = 256;
01443
01444
01445 LPBYTE pCLUT = (LPBYTE) CCMalloc(ClutSize * 3);
01446 if (pCLUT == NULL)
01447 {
01448
01449 ERROR3("No memory");
01450 return FALSE;
01451 }
01452
01453
01454 KernelDC *pDC = (KernelDC *) CCDC::ConvertFromNativeDC(pRegion->GetRenderDC());
01455
01456
01457 memset(pCLUT, 0, ClutSize);
01458
01459
01460
01461
01462 ColourContextRGBT *ccRGB = NULL;
01463 if (pSrcCLUT == m_pContonePalette)
01464 ccRGB = (ColourContextRGBT *) ColourManager::GetColourContext(COLOURMODEL_RGBT);
01465 else
01466 ccRGB = (ColourContextRGBT *) pRegion->GetRenderView()->GetColourContext(COLOURMODEL_RGBT);
01467 ERROR2IF(ccRGB == NULL, FALSE, "Can't get a ColourContextRGBT for EPS bitmap export");
01468
01469 DocColour TempCol;
01470
01471 {
01472 ColourRGBT RGB;
01473
01474
01475 for (INT32 i = 0; i < NumColours; i++)
01476 {
01477 TempCol.SetRGBValue(pSrcCLUT[i].rgbRed, pSrcCLUT[i].rgbGreen, pSrcCLUT[i].rgbBlue);
01478 ccRGB->ConvertColour(&TempCol, (ColourGeneric *) &RGB);
01479
01480 double Grey = (RGB.Red.MakeDouble() * 0.305) +
01481 (RGB.Green.MakeDouble() * 0.586) +
01482 (RGB.Blue.MakeDouble() * 0.109);
01483
01484 pCLUT[i] = (BYTE) (Grey * 255.0);
01485 }
01486 }
01487
01488
01489 pDC->OutputNewLine();
01490 pDC->OutputToken(_T("<"));
01491 pDC->OutputRawBinary(pCLUT, ClutSize);
01492 pDC->OutputToken(_T(">"));
01493 pDC->OutputNewLine();
01494
01495
01496
01497 memset(pCLUT, 0, ClutSize * 3);
01498
01499
01500 {
01501 PColourRGBT RGB;
01502
01503 for (INT32 i = 0; i < NumColours; i++)
01504 {
01505 TempCol.SetRGBValue(pSrcCLUT[i].rgbRed, pSrcCLUT[i].rgbGreen, pSrcCLUT[i].rgbBlue);
01506 ccRGB->ConvertColour(&TempCol, (ColourPacked *) &RGB);
01507
01508 pCLUT[i * 3 + 0] = RGB.Red;
01509 pCLUT[i * 3 + 1] = RGB.Green;
01510 pCLUT[i * 3 + 2] = RGB.Blue;
01511 }
01512 }
01513
01514
01515 pDC->OutputNewLine();
01516 pDC->OutputToken(_T("<"));
01517 pDC->OutputRawBinary(pCLUT, ClutSize * 3);
01518 pDC->OutputToken(_T(">"));
01519 pDC->OutputNewLine();
01520
01521
01522 CCFree(pCLUT);
01523 #endif
01524
01525 return TRUE;
01526 }
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550 BOOL CWxBitmap::ExportBitmapPalette(RenderRegion *pRegion)
01551 {
01552 #if !defined(EXCLUDE_FROM_RALPH)
01553 RebuildXPEBitmap();
01554
01555 if (!pRegion->IsKindOf(CC_RUNTIME_CLASS(CamelotEPSRenderRegion)))
01556 {
01557 ERROR3("ExportBitmapPalette called by non-CamelotEPSRenderRegion class");
01558 return(TRUE);
01559 }
01560
01561
01562
01563 ERROR3IF((BMInfo->bmiHeader.biBitCount != 1) &&
01564 (BMInfo->bmiHeader.biBitCount != 4) &&
01565 (BMInfo->bmiHeader.biBitCount != 8) &&
01566 (BMInfo->bmiHeader.biBitCount != 24) &&
01567 (BMInfo->bmiHeader.biBitCount != 32), "Bad bitmap depth in ExportBitmap!");
01568
01569
01570 if (BMInfo->bmiHeader.biBitCount > 8 || BMInfo->bmiHeader.biClrUsed < 1)
01571 return(TRUE);
01572
01573
01574 BOOL Renderable = (IS_A(pRegion, CamelotEPSRenderRegion) || pRegion->IsPrinting());
01575
01576 if (Renderable)
01577 return(ExportBitmapPaletteInternal(pRegion, BMInfo->bmiHeader.biClrUsed, BMInfo->bmiColors));
01578
01579
01580
01581 KernelDC *pDC = (KernelDC *) CCDC::ConvertFromNativeDC(pRegion->GetRenderDC());
01582
01583 pDC->OutputToken(_T("%Camelot: Bitmap palette"));
01584 pDC->OutputRawBinary((BYTE *) BMInfo->bmiColors,
01585 BMInfo->bmiHeader.biClrUsed * sizeof(RGBQUAD));
01586 pDC->OutputNewLine();
01587 #endif
01588
01589 return TRUE;
01590 }
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621 BOOL CWxBitmap::ExportSeparatedPalette(RenderRegion *pRegion)
01622 {
01623 #if !defined(EXCLUDE_FROM_RALPH)
01624 ERROR3IF(pRegion == NULL, "Illegal NULL params");
01625 if (!pRegion->IsKindOf(CC_RUNTIME_CLASS(CamelotEPSRenderRegion)))
01626 {
01627 ERROR3("ExportBitmapPalette called by non-CamelotEPSRenderRegion class");
01628 return(TRUE);
01629 }
01630
01631
01632 ERROR3IF(!pRegion->IsPrinting(), "ExportSeparatedBitmapPalette called when not printing?");
01633
01634 ERROR3IF(pRegion->GetRenderView() == NULL, "No render view");
01635 ERROR3IF(pRegion->GetRenderView()->GetColourPlate() == NULL,
01636 "Not colour separating in ExportSeparatedBitmapPalette");
01637
01638 RebuildXPEBitmap();
01639 KernelDC *pDC = (KernelDC *) CCDC::ConvertFromNativeDC(pRegion->GetRenderDC());
01640 BYTE pCLUT[256 * 3];
01641
01642 INT32 i;
01643
01644 for (i = 0; i < 256; i++)
01645 pCLUT[i] = i;
01646
01647 pDC->OutputNewLine();
01648 pDC->OutputToken(_T("<"));
01649 pDC->OutputRawBinary(pCLUT, 256);
01650 pDC->OutputToken(_T(">"));
01651 pDC->OutputNewLine();
01652
01653
01654 for (i = 0; i < 256*3; i+=3)
01655 pCLUT[i] = pCLUT[i+1] = pCLUT[i+2] = i/3;
01656
01657 pDC->OutputNewLine();
01658 pDC->OutputToken(_T("<"));
01659 pDC->OutputRawBinary(pCLUT, 256 * 3);
01660 pDC->OutputToken(_T(">"));
01661 pDC->OutputNewLine();
01662
01663 #endif
01664 return(TRUE);
01665 }
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690 BOOL CWxBitmap::ExportContonePalette(RenderRegion *pRegion)
01691 {
01692 #if !defined(EXCLUDE_FROM_RALPH)
01693 RebuildXPEBitmap();
01694 ERROR2IF(m_pContonePalette == NULL, FALSE, "No contone palette to export!");
01695
01696
01697 if (pRegion->IsKindOf(CC_RUNTIME_CLASS(CamelotEPSRenderRegion)))
01698 return(ExportBitmapPaletteInternal(pRegion, BMInfo->bmiHeader.biClrUsed, m_pContonePalette));
01699 #endif
01700
01701 return TRUE;
01702 }
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741 BOOL CWxBitmap::ExportBitmapData(RenderRegion *pRegion)
01742 {
01743 #if !defined(EXCLUDE_FROM_RALPH)
01744 RebuildXPEBitmap();
01745
01746 if (pRegion->IsKindOf(CC_RUNTIME_CLASS(CamelotEPSRenderRegion)))
01747 {
01748
01749 KernelDC *pDC = (KernelDC *) CCDC::ConvertFromNativeDC(pRegion->GetRenderDC());
01750 Filter *pFilter = pDC->GetParentFilter();
01751
01752
01753 BOOL Renderable = (IS_A(pRegion, CamelotEPSRenderRegion) || pRegion->IsPrinting());
01754
01755
01756 BOOL UseLevel2 = FALSE;
01757
01758 if (Renderable)
01759 {
01760
01761 #ifndef WEBSTER
01762 if (pRegion->IsPrinting())
01763 {
01764
01765 #ifndef STANDALONE
01766
01767 CCPrintInfo *pInfo = CCPrintInfo::GetCurrent();
01768 if (pInfo != NULL)
01769 {
01770 PrintControl *pPrCtrl = pInfo->GetPrintControl();
01771 if (pPrCtrl->GetPSLevel() == PSLEVEL_2)
01772
01773 UseLevel2 = TRUE;
01774 }
01775 #else
01776 ERROR2(FALSE,"CWxBitmap::ExportBitmapData trying to print on Viewer version!");
01777 #endif
01778 }
01779 else
01780 #endif //webster
01781 {
01782
01783 if (EPSFilter::XSEPSExportPSType == 2)
01784 UseLevel2 = TRUE;
01785 }
01786 }
01787
01788
01789 if (!Renderable)
01790 pDC->OutputToken(_T("%Camelot: Bitmap data"));
01791 pDC->OutputNewLine();
01792
01793
01794
01795
01796
01797
01798 INT32 Width = ((BMInfo->bmiHeader.biWidth * BMInfo->bmiHeader.biBitCount) + 7) / 8;
01799 INT32 Height = BMInfo->bmiHeader.biHeight;
01800
01801 INT32 Ofs = 0;
01802
01803
01804 INT32 Padding = Renderable ? 1 : 4;
01805
01806
01807 BOOL Do32bpp = pRegion->IsPrinting() && (BMInfo->bmiHeader.biBitCount == 32);
01808 if (Do32bpp)
01809 Width = BMInfo->bmiHeader.biWidth * 3;
01810
01811
01812 BOOL SwapRGB = Renderable && (BMInfo->bmiHeader.biBitCount == 24);
01813
01814
01815
01816 BOOL Expand4bpp = Renderable && (BMInfo->bmiHeader.biBitCount == 4);
01817
01818 INT32 DataSize = Width;
01819 LPBYTE pAllocatedMem = NULL;
01820 if (SwapRGB || Do32bpp)
01821 {
01822
01823
01824
01825 pAllocatedMem = (LPBYTE) CCMalloc(Width);
01826 if (pAllocatedMem == NULL)
01827
01828 return FALSE;
01829 }
01830 else if (Expand4bpp)
01831 {
01832
01833
01834 DataSize = ((BMInfo->bmiHeader.biWidth * 8) + 7) / 8;
01835 pAllocatedMem = (LPBYTE) CCMalloc(DataSize);
01836 if (pAllocatedMem == NULL)
01837
01838 return FALSE;
01839
01840
01841 }
01842
01843 LPBYTE pBuf = pAllocatedMem;
01844
01845 UINT32 ScanlineSize = DIBUtil::ScanlineSize(BMInfo->bmiHeader.biWidth,
01846 BMInfo->bmiHeader.biBitCount);
01847
01848
01849 if (UseLevel2)
01850 {
01851 if (!pDC->StartASCII85Output(TRUE))
01852
01853 return FALSE;
01854 }
01855
01856
01857 for (INT32 i = 0; i < Height; i++)
01858 {
01859 if (Do32bpp)
01860 {
01861
01862
01863 INT32 k = Ofs;
01864 for (INT32 j = 0; j < Width; j += 3)
01865 {
01866 pBuf[j] = BMBytes[k + 2];
01867 pBuf[j + 1] = BMBytes[k + 1];
01868 pBuf[j + 2] = BMBytes[k];
01869
01870 k += 4;
01871 }
01872 }
01873 else if (SwapRGB)
01874 {
01875
01876
01877 for (INT32 j = 0; j < Width; j += 3)
01878 {
01879 pBuf[j] = BMBytes[Ofs + j + 2];
01880 pBuf[j + 1] = BMBytes[Ofs + j + 1];
01881 pBuf[j + 2] = BMBytes[Ofs + j];
01882 }
01883 }
01884 else if (Expand4bpp)
01885 {
01886
01887 INT32 k = 0;
01888 for (INT32 j = 0; j < Width; j++)
01889 {
01890 pBuf[k++] = (BMBytes[Ofs + j] & 0xF0) >> 4;
01891 pBuf[k++] = BMBytes[Ofs + j] & 0xF;
01892 }
01893 }
01894 else
01895
01896 pBuf = BMBytes + Ofs;
01897
01898
01899 INT32 nBytes;
01900
01901 if (UseLevel2)
01902
01903 nBytes = pDC->OutputASCII85(pBuf, DataSize);
01904 else
01905
01906 nBytes = pDC->OutputRawBinary(pBuf, DataSize, Padding);
01907
01908 if (nBytes == -1)
01909 {
01910
01911 if (pAllocatedMem != NULL)
01912 CCFree(pAllocatedMem);
01913
01914 return FALSE;
01915 }
01916
01917
01918 if (pFilter != NULL)
01919 pFilter->UpdateExportedNodeCount(1);
01920
01921
01922 Ofs += ScanlineSize;
01923 }
01924
01925 if (UseLevel2)
01926 {
01927 if (!pDC->EndASCII85Output())
01928
01929 return FALSE;
01930 }
01931
01932
01933 if (pAllocatedMem != NULL)
01934 CCFree(pAllocatedMem);
01935 }
01936 #endif
01937
01938 return TRUE;
01939 }
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986 BOOL CWxBitmap::ExportSeparatedData(RenderRegion *pRegion, BYTE *SepTables)
01987 {
01988 #ifndef STANDALONE
01989 ERROR3IF(pRegion == NULL || SepTables == NULL, "Illegal NULL params");
01990
01991 if (!pRegion->IsKindOf(CC_RUNTIME_CLASS(CamelotEPSRenderRegion)))
01992 {
01993 ERROR3("Not a CamelotEPSRenderRegion derived RenderRegion - bitmap not exported");
01994 return(TRUE);
01995 }
01996
01997 RebuildXPEBitmap();
01998 KernelDC *pDC = (KernelDC *) CCDC::ConvertFromNativeDC(pRegion->GetRenderDC());
01999 Filter *pFilter = pDC->GetParentFilter();
02000
02001
02002 BOOL UseLevel2 = FALSE;
02003 BOOL Renderable = (IS_A(pRegion, CamelotEPSRenderRegion) || pRegion->IsPrinting());
02004
02005 if (Renderable)
02006 {
02007
02008 #ifndef WEBSTER
02009 if (pRegion->IsPrinting())
02010 {
02011
02012 CCPrintInfo *pInfo = CCPrintInfo::GetCurrent();
02013 if (pInfo != NULL)
02014 {
02015 PrintControl *pPrCtrl = pInfo->GetPrintControl();
02016 UseLevel2 = (pPrCtrl->GetPSLevel() == PSLEVEL_2);
02017 }
02018 }
02019 else
02020 #endif //webster
02021
02022 UseLevel2 = (EPSFilter::XSEPSExportPSType == 2);
02023 }
02024
02025
02026 if (!Renderable)
02027 pDC->OutputToken(_T("%Camelot: Bitmap data"));
02028 pDC->OutputNewLine();
02029
02030
02031
02032 const INT32 PixelWidth = BMInfo->bmiHeader.biWidth;
02033 const INT32 PixelHeight = BMInfo->bmiHeader.biHeight;
02034 const INT32 ByteWidth = PixelWidth;
02035
02036
02037
02038 BYTE *pOutputBuffer = (BYTE *) CCMalloc(ByteWidth);
02039 if (pOutputBuffer == NULL)
02040 {
02041 ERROR3("Scanline buffer allocation failed");
02042 return(FALSE);
02043 }
02044
02045 Pixel32bpp *pInputBuffer = (Pixel32bpp *) CCMalloc(PixelWidth * sizeof(Pixel32bpp));
02046 if (pInputBuffer == NULL)
02047 {
02048 ERROR3("No memory for 32bpp separation scanline");
02049 return(FALSE);
02050 }
02051
02052
02053 if (UseLevel2 && !pDC->StartASCII85Output(TRUE))
02054 {
02055 ERROR3("StartASCII85Output failed");
02056 return(FALSE);
02057 }
02058
02059
02060 ColourContext *OutputContext = NULL;
02061 if (SepTables != NULL)
02062 {
02063 ERROR3IF(pRegion->GetRenderView() == NULL, "Darn");
02064 OutputContext = pRegion->GetRenderView()->GetColourContext(COLOURMODEL_RGBT);
02065
02066 ERROR3IF(OutputContext == NULL, "Double Darn");
02067 }
02068
02069 INT32 nBytes;
02070 for (INT32 y = 0; y < PixelHeight; y++)
02071 {
02072 GetScanline32bpp(y, TRUE, pInputBuffer);
02073 ColourSeparateScanline32to8(OutputContext, SepTables, pOutputBuffer, pInputBuffer, PixelWidth);
02074
02075
02076 if (UseLevel2)
02077 nBytes = pDC->OutputASCII85(pOutputBuffer, ByteWidth);
02078 else
02079 nBytes = pDC->OutputRawBinary(pOutputBuffer, ByteWidth, (Renderable) ? 1 : 4);
02080
02081 if (nBytes == -1)
02082 {
02083 ERROR3("EPS output failed - Out of disc space?");
02084 CCFree(pOutputBuffer);
02085 return(FALSE);
02086 }
02087
02088
02089 if (pFilter != NULL)
02090 pFilter->UpdateExportedNodeCount(1);
02091 }
02092
02093 CCFree(pInputBuffer);
02094 CCFree(pOutputBuffer);
02095
02096 if (UseLevel2 && !pDC->EndASCII85Output())
02097 {
02098 ERROR3("EndASCII85Output failed");
02099 return(FALSE);
02100 }
02101 return(TRUE);
02102 #else
02103 ERROR2(FALSE,"CWxBitmap::SeparateBitmapData being called in Viewer version!");
02104 #endif
02105 }
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140 BOOL CWxBitmap::GetScanline32bpp(UINT32 YPos, BOOL UsePalette, Pixel32bpp *Scanline)
02141 {
02142 RebuildXPEBitmap();
02143 ERROR3IF(YPos < 0 || YPos > GetHeight(), "Illegal Y position");
02144 ERROR3IF(Scanline == NULL, "Illegal NULL param");
02145
02146 for (UINT32 XPos = 0; XPos < GetWidth(); XPos++)
02147 Scanline[XPos] = ReadPixel32bpp(XPos, YPos, UsePalette);
02148
02149 return(TRUE);
02150 }
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183 wxImage * CWxBitmap::MakewxImage(UINT32 ImageWidth, UINT32 ImageHeight, BOOL UsePalette)
02184 {
02185 if (!ImageWidth)
02186 ImageWidth=GetWidth();
02187 if (!ImageHeight)
02188 ImageHeight=GetHeight();
02189
02190 wxImage * pImage = new wxImage(GetWidth(), GetHeight(), false);
02191 if (!pImage)
02192 return NULL;
02193 #if 0
02194 pImage->SetAlpha();
02195 if (!pImage->HasAlpha())
02196 {
02197 delete pImage;
02198 return NULL;
02199 }
02200 #endif
02201
02202 RebuildXPEBitmap();
02203
02204 double xstep = GetWidth()/ImageWidth;
02205 double ystep = GetHeight()/ImageHeight;
02206 double x=0;
02207 double y=0;
02208
02209 for (UINT32 YPos = 0; YPos < ImageHeight; YPos++)
02210 {
02211 UINT32 YP=(UINT32)(y+0.5);
02212 x=0;
02213 for (UINT32 XPos = 0; XPos < ImageWidth; XPos++)
02214 {
02215 UINT32 XP=(UINT32)(x+0.5);
02216 Pixel32bpp p = ReadPixel32bpp(XP, YP, UsePalette);
02217 pImage->SetRGB(XPos, YPos, p.Red, p.Blue, p.Green);
02218
02219
02220 x+=xstep;
02221 }
02222 y+=ystep;
02223 }
02224
02225 return(pImage);
02226 }
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260 void CWxBitmap::ColourSeparateScanline32to8(ColourContext *OutputContext, BYTE *SepTables,
02261 BYTE *DestBuffer, Pixel32bpp *SrcBuffer,
02262 INT32 PixelWidth)
02263 {
02264 ERROR3IF(DestBuffer == NULL || SrcBuffer == NULL || PixelWidth < 1, "Illegal params");
02265 ERROR3IF(SepTables == NULL, "No separation tables!?");
02266 ERROR3IF(OutputContext == NULL || OutputContext->GetColourPlate() == NULL,
02267 "The separation ColourPlate has gone missing!");
02268
02269
02270
02271
02272
02273 BYTE Temp;
02274 #define TEMPMAX(R,G,B) \
02275 { \
02276 Temp = ((R) > (G)) ? (R) : (G); \
02277 Temp = (Temp > (B)) ? Temp : (B); \
02278 }
02279
02280
02281
02282 INT32 i;
02283 BYTE Ink;
02284
02285 BYTE *UCR = SepTables + 768 + 255;
02286
02287
02288 ColourPlateType Plate = OutputContext->GetColourPlate()->GetType();
02289 BOOL bNegate = OutputContext->GetColourPlate()->IsNegative();
02290 BYTE *LUT = NULL;
02291
02292 switch (Plate)
02293 {
02294 case COLOURPLATE_SPOT:
02295 for (i = 0; i < PixelWidth; i++)
02296 DestBuffer[i] = 255;
02297 return;
02298 break;
02299
02300 case COLOURPLATE_CYAN:
02301 LUT = SepTables + 0;
02302 break;
02303
02304 case COLOURPLATE_MAGENTA:
02305 LUT = SepTables + 256;
02306 break;
02307
02308 case COLOURPLATE_YELLOW:
02309 LUT = SepTables + 512;
02310 break;
02311
02312 default:
02313 LUT = SepTables + 1024;
02314 break;
02315 }
02316
02317 PORTNOTE("cms", "Disabled XaraCMS")
02318 #ifndef EXCLUDE_FROM_XARALX
02319 BOOL PrintRGBBlackAsKey = XaraCMS::PrintRGBBlackAsKey;
02320 #else
02321 BOOL PrintRGBBlackAsKey = TRUE;
02322 #endif
02323
02324 for (i = 0; i < PixelWidth; i++)
02325 {
02326
02327 TEMPMAX(SrcBuffer[i].Red, SrcBuffer[i].Green, SrcBuffer[i].Blue);
02328
02329 if (!PrintRGBBlackAsKey || Temp > 0)
02330 {
02331 switch (Plate)
02332 {
02333 case COLOURPLATE_CYAN:
02334 Ink = 255 - SrcBuffer[i].Red;
02335 if (Ink>UCR[-Temp])
02336 Ink -= UCR[-Temp];
02337 else
02338 Ink=0;
02339 break;
02340
02341 case COLOURPLATE_MAGENTA:
02342 Ink = 255 - SrcBuffer[i].Green;
02343 if (Ink>UCR[-Temp])
02344 Ink -= UCR[-Temp];
02345 else
02346 Ink=0;
02347 break;
02348
02349 case COLOURPLATE_YELLOW:
02350 Ink = 255 - SrcBuffer[i].Blue;
02351 if (Ink>UCR[-Temp])
02352 Ink -= UCR[-Temp];
02353 else
02354 Ink=0;
02355 break;
02356
02357 default:
02358 Ink = 255 - Temp;
02359 break;
02360 }
02361
02362 Ink = LUT[Ink];
02363 }
02364 else
02365 {
02366 Ink = (Plate == COLOURPLATE_KEY) ? 255 : 0;
02367 }
02368
02369 if (bNegate)
02370 DestBuffer[i] = Ink;
02371 else
02372 DestBuffer[i] = 255 - Ink;
02373 }
02374
02375 #undef TEMPMAX
02376 }
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395 void CWxBitmap::ColourSeparate32to32(ColourPlate *pPlate, BYTE *SepTables)
02396 {
02397 ERROR3IF(SepTables == NULL, "No separation tables!?");
02398 ERROR3IF(pPlate == NULL, "The separation ColourPlate has gone missing!");
02399
02400 RebuildXPEBitmap();
02401
02402 ERROR3IF(GetBPP() != 32, "Bitmap not 32bpp!");
02403
02404 DWORD NumPixels = GetWidth() * GetHeight();
02405 BGRT* pPixel = (BGRT*)GetBitmapBits();
02406
02407
02408
02409
02410 BYTE Temp;
02411 #define TEMPMAX(R,G,B) \
02412 { \
02413 Temp = ((R) > (G)) ? (R) : (G); \
02414 Temp = (Temp > (B)) ? Temp : (B); \
02415 }
02416
02417
02418 DWORD i;
02419 BYTE Ink;
02420
02421 BYTE *UCR = SepTables + 768 + 255;
02422
02423
02424 ColourPlateType Plate = pPlate->GetType();
02425 ColourPlateType OutputPlate = pPlate->IsMonochrome() ? COLOURPLATE_KEY : Plate;
02426 BOOL bNegate = pPlate->IsNegative();
02427 BYTE *LUT = NULL;
02428
02429 switch (Plate)
02430 {
02431 case COLOURPLATE_CYAN:
02432 LUT = SepTables + 0;
02433 break;
02434
02435 case COLOURPLATE_MAGENTA:
02436 LUT = SepTables + 256;
02437 break;
02438
02439 case COLOURPLATE_YELLOW:
02440 LUT = SepTables + 512;
02441 break;
02442
02443 default:
02444 LUT = SepTables + 1024;
02445 break;
02446 }
02447
02448 PORTNOTE("cms", "Disabled XaraCMS")
02449 #ifndef EXCLUDE_FROM_XARALX
02450 BOOL PrintRGBBlackAsKey = XaraCMS::PrintRGBBlackAsKey;
02451 #else
02452 BOOL PrintRGBBlackAsKey = TRUE;
02453 #endif
02454
02455 for (i = 0; i < NumPixels; i++)
02456 {
02457
02458 TEMPMAX(pPixel[i].Red, pPixel[i].Green, pPixel[i].Blue);
02459
02460 if (!PrintRGBBlackAsKey || Temp > 0)
02461 {
02462 switch (Plate)
02463 {
02464 case COLOURPLATE_CYAN:
02465 Ink = 255 - pPixel[i].Red;
02466 if (Ink>UCR[-Temp])
02467 Ink -= UCR[-Temp];
02468 else
02469 Ink=0;
02470 break;
02471
02472 case COLOURPLATE_MAGENTA:
02473 Ink = 255 - pPixel[i].Green;
02474 if (Ink>UCR[-Temp])
02475 Ink -= UCR[-Temp];
02476 else
02477 Ink=0;
02478 break;
02479
02480 case COLOURPLATE_YELLOW:
02481 Ink = 255 - pPixel[i].Blue;
02482 if (Ink>UCR[-Temp])
02483 Ink -= UCR[-Temp];
02484 else
02485 Ink=0;
02486 break;
02487
02488 default:
02489 Ink = 255 - Temp;
02490 break;
02491 }
02492
02493 Ink = LUT[Ink];
02494 }
02495 else
02496 {
02497 Ink = (Plate == COLOURPLATE_KEY) ? 255 : 0;
02498 }
02499
02500 if (bNegate)
02501 Ink = 255 - Ink;
02502
02503 switch (OutputPlate)
02504 {
02505 case COLOURPLATE_CYAN:
02506 pPixel[i].Red = 255 - Ink;
02507 pPixel[i].Green = 255;
02508 pPixel[i].Blue = 255;
02509 break;
02510
02511 case COLOURPLATE_MAGENTA:
02512 pPixel[i].Red = 255;
02513 pPixel[i].Green = 255 - Ink;
02514 pPixel[i].Blue = 255;
02515 break;
02516
02517 case COLOURPLATE_YELLOW:
02518 pPixel[i].Red = 255;
02519 pPixel[i].Green = 255;
02520 pPixel[i].Blue = 255 - Ink;
02521 break;
02522
02523 default:
02524 pPixel[i].Red = 255 - Ink;
02525 pPixel[i].Green = 255 - Ink;
02526 pPixel[i].Blue = 255 - Ink;
02527 break;
02528 }
02529 }
02530
02531 #undef TEMPMAX
02532 }
02533
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547 OILBitmap* CWxBitmap::MakeSeparatedCopy(ColourPlate *pPlate, BYTE *SepTables)
02548 {
02549 ERROR3IF(SepTables == NULL, "No separation tables!?");
02550 ERROR3IF(pPlate == NULL, "The separation ColourPlate has gone missing!");
02551
02552 if (SepTables == NULL || pPlate == NULL)
02553 return(NULL);
02554
02555 RebuildXPEBitmap();
02556
02557 if (BMInfo == NULL || BMBytes == NULL)
02558 {
02559 ERROR3("This bitmap has no bits or info to copy!");
02560 return NULL;
02561 }
02562
02563 LPBYTE pNewBits = NULL;
02564 LPBITMAPINFO pNewInfo = NULL;
02565
02566 pNewInfo = AllocDIB(BMInfo->bmiHeader.biWidth, BMInfo->bmiHeader.biHeight, 32, &pNewBits);
02567
02568 if (pNewInfo == NULL || pNewBits == NULL)
02569 {
02570 ERROR3("Failed to allocate bitmap structures");
02571 return NULL;
02572 }
02573
02574 Pixel32bpp *pScanline = (Pixel32bpp *) CCMalloc(BMInfo->bmiHeader.biWidth * sizeof(Pixel32bpp));
02575 if (pScanline == NULL)
02576 return(NULL);
02577 BGRT* pPixel = (BGRT*)pNewBits;
02578
02579
02580
02581
02582 BYTE Temp;
02583 #define TEMPMAX(R,G,B) \
02584 { \
02585 Temp = ((R) > (G)) ? (R) : (G); \
02586 Temp = (Temp > (B)) ? Temp : (B); \
02587 }
02588
02589
02590 INT32 scan;
02591 INT32 i;
02592 BYTE Ink;
02593
02594 BYTE *UCR = SepTables + 768 + 255;
02595
02596
02597 ColourPlateType Plate = pPlate->GetType();
02598 ColourPlateType OutputPlate = pPlate->IsMonochrome() ? COLOURPLATE_KEY : Plate;
02599 BOOL bNegate = pPlate->IsNegative();
02600 BYTE *LUT = NULL;
02601
02602 switch (Plate)
02603 {
02604 case COLOURPLATE_CYAN:
02605 LUT = SepTables + 0;
02606 break;
02607
02608 case COLOURPLATE_MAGENTA:
02609 LUT = SepTables + 256;
02610 break;
02611
02612 case COLOURPLATE_YELLOW:
02613 LUT = SepTables + 512;
02614 break;
02615
02616 default:
02617 LUT = SepTables + 1024;
02618 break;
02619 }
02620
02621 PORTNOTE("cms", "Disabled XaraCMS")
02622 #ifndef EXCLUDE_FROM_XARALX
02623 BOOL PrintRGBBlackAsKey = XaraCMS::PrintRGBBlackAsKey;
02624 #else
02625 BOOL PrintRGBBlackAsKey = TRUE;
02626 #endif
02627
02628 for (scan = 0; scan < BMInfo->bmiHeader.biHeight; scan++)
02629 {
02630 GetScanline32bpp(scan, TRUE, pScanline);
02631 for (i = 0; i < BMInfo->bmiHeader.biWidth; i++)
02632 {
02633
02634 TEMPMAX(pScanline[i].Red, pScanline[i].Green, pScanline[i].Blue);
02635
02636 if (!PrintRGBBlackAsKey || Temp > 0)
02637 {
02638 switch (Plate)
02639 {
02640 case COLOURPLATE_CYAN:
02641 Ink = 255 - pScanline[i].Red;
02642 if (Ink>UCR[-Temp])
02643 Ink -= UCR[-Temp];
02644 else
02645 Ink=0;
02646 break;
02647
02648 case COLOURPLATE_MAGENTA:
02649 Ink = 255 - pScanline[i].Green;
02650 if (Ink>UCR[-Temp])
02651 Ink -= UCR[-Temp];
02652 else
02653 Ink=0;
02654 break;
02655
02656 case COLOURPLATE_YELLOW:
02657 Ink = 255 - pScanline[i].Blue;
02658 if (Ink>UCR[-Temp])
02659 Ink -= UCR[-Temp];
02660 else
02661 Ink=0;
02662 break;
02663
02664 default:
02665 Ink = 255 - Temp;
02666 break;
02667 }
02668
02669 Ink = LUT[Ink];
02670 }
02671 else
02672 {
02673 Ink = (Plate == COLOURPLATE_KEY) ? 255 : 0;
02674 }
02675
02676 if (bNegate)
02677 Ink = 255 - Ink;
02678
02679 switch (OutputPlate)
02680 {
02681 case COLOURPLATE_CYAN:
02682 pPixel[i].Red = 255 - Ink;
02683 pPixel[i].Green = 255;
02684 pPixel[i].Blue = 255;
02685 break;
02686
02687 case COLOURPLATE_MAGENTA:
02688 pPixel[i].Red = 255;
02689 pPixel[i].Green = 255 - Ink;
02690 pPixel[i].Blue = 255;
02691 break;
02692
02693 case COLOURPLATE_YELLOW:
02694 pPixel[i].Red = 255;
02695 pPixel[i].Green = 255;
02696 pPixel[i].Blue = 255 - Ink;
02697 break;
02698
02699 default:
02700 pPixel[i].Red = 255 - Ink;
02701 pPixel[i].Green = 255 - Ink;
02702 pPixel[i].Blue = 255 - Ink;
02703 break;
02704 }
02705 pPixel[i].Transparency = pScanline[i].Alpha;
02706 }
02707 pPixel += BMInfo->bmiHeader.biWidth;
02708 }
02709
02710
02711 #undef TEMPMAX
02712
02713 CWxBitmap* pNewBitmap = new CWxBitmap(pNewInfo, pNewBits);
02714
02715 CCFree(pScanline);
02716
02717 if (pNewBitmap == NULL)
02718 {
02719 ERROR3("Failed to allocate new CWxBitmap");
02720 FreeDIB(pNewInfo, pNewBits);
02721 }
02722 return pNewBitmap;
02723 }
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742 BOOL CWxBitmap::WritePalette(BaseCamelotFilter* pFilter)
02743 {
02744 ERROR2IF(pFilter == NULL,FALSE,"CWxBitmap::WritePalette null pFilter");
02745 RebuildXPEBitmap();
02746
02747 BOOL ok = TRUE;
02748
02749 UINT32 NumberOfPaletteEntries = GetNumPaletteEntries();
02750 ERROR2IF(NumberOfPaletteEntries == 0 || NumberOfPaletteEntries > 256, FALSE,"Palette entries 0 or > 256!");
02751
02752 BYTE Entries = NumberOfPaletteEntries - 1;
02753 if (ok) ok = pFilter->Write(Entries);
02754 for (UINT32 i = 0; i < NumberOfPaletteEntries; i++)
02755 {
02756 #if !defined(__WXMSW__)
02757
02758 if (ok) ok = pFilter->Write(BMInfo->bmiColors[i].rgbBlue);
02759 if (ok) ok = pFilter->Write(BMInfo->bmiColors[i].rgbGreen);
02760 if (ok) ok = pFilter->Write(BMInfo->bmiColors[i].rgbRed);
02761 #else
02762
02763 if (ok) ok = pFilter->Write(BMInfo->bmiColors[i].rgbRed);
02764 if (ok) ok = pFilter->Write(BMInfo->bmiColors[i].rgbGreen);
02765 if (ok) ok = pFilter->Write(BMInfo->bmiColors[i].rgbBlue);
02766 #endif
02767 }
02768
02769
02770
02771 pFilter->IncProgressBarCount(NumberOfPaletteEntries);
02772
02773 return ok;
02774 }
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793 BOOL CWxBitmap::Convert24To8(RGBTRIPLE *pPalette, UINT32 NumberOfPaletteEntries)
02794 {
02795 ERROR2IF(pPalette == NULL,FALSE,"KernelBitmap::Convert24To8 null pFilter");
02796 ERROR2IF(NumberOfPaletteEntries == 0,FALSE,"KernelBitmap::Convert24To8 NumberOfPaletteEntries = 0");
02797 RebuildXPEBitmap();
02798
02799 BOOL ok = TRUE;
02800 TRACEUSER("Neville", wxT("CWxBitmap::Convert24To8 NumberOfPaletteEntries = %d\n"),NumberOfPaletteEntries);
02801
02802 LPBITMAPINFO pDestBMInfo = NULL;
02803 LPBYTE pDestBMBytes = NULL;
02804
02805
02806 ok = DIBUtil::Convert24to8( BMInfo, BMBytes, &pDestBMInfo, &pDestBMBytes,
02807 pPalette, NumberOfPaletteEntries);
02808
02809 if (ok)
02810 {
02811
02812 FreeDIB( BMInfo, BMBytes );
02813
02814
02815 BMInfo = pDestBMInfo;
02816 BMBytes = pDestBMBytes;
02817
02818 pDestBMInfo = NULL;
02819 pDestBMBytes = NULL;
02820
02821 ScanLineByteWidth = 0;
02822 BitmapSize = 0;
02823
02824 CacheGeometry();
02825 }
02826
02827 if (pDestBMInfo != NULL)
02828 {
02829 delete pDestBMInfo;
02830 }
02831
02832 if (pDestBMBytes != NULL)
02833 {
02834 delete pDestBMBytes;
02835 }
02836
02837 return ok;
02838 }
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862
02863
02864
02865 BOOL CWxBitmap::ImportBitmap(CCLexFile* pFile, BaseBitmapFilter* pBitmapFilter,
02866 BaseCamelotFilter* pFilter, BOOL IsCompressed)
02867 {
02868 ERROR2IF(pFile == NULL,FALSE,"CWxBitmap::ImportBitmap null pFile");
02869 ERROR2IF(pBitmapFilter == NULL,FALSE,"CWxBitmap::ImportBitmap null pBitmapFilter");
02870 ERROR2IF(pFilter == NULL,FALSE,"CWxBitmap::ImportBitmap null pFilter");
02871
02872
02873
02874 if (pBitmapFilter->ReadFromFile(this, pFilter, pFile, IsCompressed))
02875 {
02876 CacheGeometry();
02877 return TRUE;
02878 }
02879
02880 return FALSE;
02881 }
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906
02907 BOOL CWxBitmap::ImportBitmap(Filter *pFilter, const BitmapInfo *pInfo, INT32 BitmapType)
02908 {
02909
02910
02911
02912
02913 if (pFilter->IsKindOf(CC_RUNTIME_CLASS(BaseBitmapFilter)))
02914 {
02915 BaseBitmapFilter* pBitmapFilter = (BaseBitmapFilter*)pFilter;
02916
02917
02918
02919 if (pBitmapFilter->ReadFromFile(this))
02920 {
02921 CacheGeometry();
02922 return TRUE;
02923 }
02924 else
02925 return FALSE;
02926 }
02927
02928 if (!pFilter->IsKindOf(CC_RUNTIME_CLASS(CamelotEPSFilter)))
02929 {
02930 ENSURE(FALSE, "Trying to import a bitmap with a non-Camelot EPS filter");
02931 return FALSE;
02932 }
02933
02934
02935 ENSURE((pInfo->PixelDepth == 1) ||
02936 (pInfo->PixelDepth == 4) ||
02937 (pInfo->PixelDepth == 8) ||
02938 (pInfo->PixelDepth == 24) ||
02939 (pInfo->PixelDepth == 32), "Bad bitmap depth in ImportBitmap!");
02940
02941 if ((pInfo->NumPaletteEntries > 0) && (pInfo->PixelDepth > 8))
02942 {
02943 ENSURE(FALSE, "We don't support palettes on bitmaps >8bpp!");
02944 }
02945
02946
02947
02948
02949
02950
02951
02952
02953 CamelotEPSFilter *pEPSFilter = (CamelotEPSFilter *) pFilter;
02954
02955 ENSURE((BMInfo == NULL) && (BMBytes == NULL),
02956 "Trying to import into an existing bitmap");
02957
02958
02959 BMInfo = AllocDIB(pInfo->PixelWidth, pInfo->PixelHeight, pInfo->PixelDepth,
02960 &BMBytes, NULL);
02961 if (BMInfo == NULL)
02962 {
02963
02964 ENSURE(FALSE, "Failed to allocate memory to import bitmap!");
02965 return FALSE;
02966 }
02967
02968
02969
02970
02971
02972
02973
02974 double xppm = ((double)pInfo->PixelWidth * M_MP_VAL)/ (double)(pInfo->RecommendedWidth);
02975 double yppm = ((double)pInfo->PixelHeight * M_MP_VAL)/ (double)(pInfo->RecommendedHeight);
02976 BMInfo->bmiHeader.biXPelsPerMeter = (INT32)(xppm + 0.5);
02977 BMInfo->bmiHeader.biYPelsPerMeter = (INT32)(yppm + 0.5);
02978
02979 if ((BMInfo->bmiHeader.biXPelsPerMeter < 0) ||
02980 (BMInfo->bmiHeader.biYPelsPerMeter < 0))
02981 {
02982 ENSURE(FALSE, "Bad pixel size");
02983 return FALSE;
02984 }
02985
02986
02987 if (((pInfo->PixelDepth <= 8)) && (pInfo->NumPaletteEntries > 0))
02988 {
02989 if (!pEPSFilter->ImportBinary((BYTE *) BMInfo->bmiColors,
02990 BMInfo->bmiHeader.biClrUsed * sizeof(RGBQUAD)))
02991 {
02992
02993 return FALSE;
02994 }
02995 }
02996
02997
02998 CacheGeometry();
02999
03000
03001
03002
03003
03004 if (pFilter->IsKindOf(CC_RUNTIME_CLASS(CamelotNativeEPSFilter)))
03005 {
03006
03007 INT32 NumScanLines = pInfo->PixelHeight;
03008 for (INT32 i=0; i<NumScanLines; i++)
03009 {
03010
03011 if (!pEPSFilter->ImportBinary(BMBytes + (i*ScanLineByteWidth), ScanLineByteWidth))
03012 return FALSE;
03013 }
03014
03015
03016 return TRUE;
03017 }
03018 else
03019 {
03020
03021 return pEPSFilter->ImportBinary(BMBytes, BMInfo->bmiHeader.biSizeImage);
03022 }
03023
03024
03025 return FALSE;
03026 }
03027
03028
03029
03030
03031
03032
03033
03034
03035
03036
03037
03038
03039
03040
03041
03042
03043
03044
03045
03046
03047
03048
03049
03050
03051
03052
03053
03054
03055
03056
03057
03058 void CWxBitmap::PlotPixel(INT32 x, INT32 y, Pixel32bpp NewValue)
03059 {
03060 RebuildXPEBitmap();
03061 ERROR3IF(BMInfo == NULL || BMBytes == NULL, "PlotPixel called on duff bitmap");
03062 ERROR3IF(x < 0 || y < 0 || x >= (INT32)GetWidth() || y >= (INT32)GetHeight(),
03063 "Illegal pixel position in CWxBitmap::PlotPixel");
03064
03065 BYTE *ScanlineStart = BMBytes + (y * ScanLineByteWidth);
03066
03067 switch(BMInfo->bmiHeader.biBitCount)
03068 {
03069 case 16:
03070 ERROR3("Unimplemented code");
03071 break;
03072
03073 case 24:
03074 ScanlineStart[x * 3 + 0] = NewValue.Red;
03075 ScanlineStart[x * 3 + 1] = NewValue.Green;
03076 ScanlineStart[x * 3 + 2] = NewValue.Blue;
03077 break;
03078
03079 case 32:
03080 ScanlineStart[x * 4 + 0] = NewValue.Red;
03081 ScanlineStart[x * 4 + 1] = NewValue.Green;
03082 ScanlineStart[x * 4 + 2] = NewValue.Blue;
03083 ScanlineStart[x * 4 + 3] = NewValue.Alpha;
03084 break;
03085
03086 default:
03087 ERROR3("Unsupported (non-deep) bitmap format in PlotPixel(32bpp)");
03088 break;
03089 }
03090 }
03091
03092
03093
03094
03095
03096
03097
03098
03099
03100
03101
03102
03103
03104
03105
03106
03107
03108
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125 void CWxBitmap::PlotPixel(INT32 x, INT32 y, PixelGreyscale NewValue)
03126 {
03127 RebuildXPEBitmap();
03128 ERROR3IF(BMInfo == NULL || BMBytes == NULL, "PlotPixel called on duff bitmap");
03129 ERROR3IF(x < 0 || y < 0 || x >= (INT32)GetWidth() || y >= (INT32)GetHeight(),
03130 "Illegal pixel position in CWxBitmap::PlotPixel");
03131
03132 BYTE *ScanlineStart = BMBytes + (y * ScanLineByteWidth);
03133
03134 switch(BMInfo->bmiHeader.biBitCount)
03135 {
03136 case 8:
03137 ScanlineStart[x] = NewValue;
03138 break;
03139
03140 case 24:
03141 ScanlineStart[x * 3 + 0] = \
03142 ScanlineStart[x * 3 + 1] = \
03143 ScanlineStart[x * 3 + 2] = NewValue;
03144 break;
03145
03146 case 32:
03147 ScanlineStart[x * 4 + 0] = \
03148 ScanlineStart[x * 4 + 1] = \
03149 ScanlineStart[x * 4 + 2] = NewValue;
03150
03151 ScanlineStart[x * 4 + 3] = 0;
03152 break;
03153
03154 default:
03155 ERROR3("Unsupported bitmap format in PlotPixel(8bpp)");
03156 break;
03157 }
03158 }
03159
03160
03161
03162
03163
03164
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195 inline Pixel32bpp CWxBitmap::ReadPixel32bpp(INT32 x, INT32 y, BOOL UsePalette)
03196 {
03197 RebuildXPEBitmap();
03198 ERROR3IF(BMInfo == NULL || BMBytes == NULL, "PlotPixel called on duff bitmap");
03199 ERROR3IF(x < 0 || y < 0 || x >= (INT32)GetWidth() || y >= (INT32)GetHeight(),
03200 "Illegal pixel position in CWxBitmap::ReadPixel");
03201
03202 BYTE *ScanlineStart = BMBytes + (y * ScanLineByteWidth);
03203
03204 Pixel32bpp Pix;
03205 Pix.Alpha = 0;
03206
03207 if (UsePalette && BMInfo->bmiHeader.biClrUsed < 1)
03208 UsePalette = FALSE;
03209
03210 switch(BMInfo->bmiHeader.biBitCount)
03211 {
03212 case 1:
03213 {
03214 BYTE Temp = ScanlineStart[x >> 3];
03215 Temp &= 0x80 >> (x & 7);
03216
03217
03218 if (UsePalette)
03219 {
03220 Temp = (Temp == 0) ? 0 : 1;
03221 Pix.Red = BMInfo->bmiColors[Temp].rgbRed;
03222 Pix.Green = BMInfo->bmiColors[Temp].rgbGreen;
03223 Pix.Blue = BMInfo->bmiColors[Temp].rgbBlue;
03224 }
03225 else
03226 {
03227 Temp = (Temp == 0) ? 0 : 255;
03228 Pix.Red = Pix.Green = Pix.Blue = Temp;
03229 }
03230 }
03231 break;
03232
03233 case 4:
03234 {
03235 BYTE Temp = ScanlineStart[x / 2];
03236
03237
03238 if (UsePalette)
03239 {
03240
03241 if ((x & 1) == 0)
03242 Temp = (Temp >> 4) & 0x0f;
03243 else
03244 Temp &= 0x0f;
03245
03246 Pix.Red = BMInfo->bmiColors[Temp].rgbRed;
03247 Pix.Green = BMInfo->bmiColors[Temp].rgbGreen;
03248 Pix.Blue = BMInfo->bmiColors[Temp].rgbBlue;
03249 }
03250 else
03251 {
03252
03253
03254 if ((x & 1) == 0)
03255 Temp = (Temp & 0xf0) | ((Temp & 0xf0) >> 4);
03256 else
03257 Temp = (Temp & 0x0f) | ((Temp & 0x0f) << 4);
03258
03259 Pix.Red = Pix.Green = Pix.Blue = Temp;
03260 }
03261 }
03262 break;
03263
03264 case 8:
03265
03266 if (UsePalette)
03267 {
03268 Pix.Red = BMInfo->bmiColors[ScanlineStart[x]].rgbRed;
03269 Pix.Green = BMInfo->bmiColors[ScanlineStart[x]].rgbGreen;
03270 Pix.Blue = BMInfo->bmiColors[ScanlineStart[x]].rgbBlue;
03271 }
03272 else
03273 Pix.Red = Pix.Green = Pix.Blue = ScanlineStart[x];
03274 break;
03275
03276 case 24:
03277 x *= 3;
03278 Pix.Blue = ScanlineStart[x++];
03279 Pix.Green = ScanlineStart[x++];
03280 Pix.Red = ScanlineStart[x++];
03281 break;
03282
03283 case 32:
03284 x *= 4;
03285 Pix.Blue = ScanlineStart[x++];
03286 Pix.Green = ScanlineStart[x++];
03287 Pix.Red = ScanlineStart[x++];
03288 Pix.Alpha = ScanlineStart[x++];
03289 break;
03290
03291 default:
03292 Pix.Red = Pix.Green = Pix.Blue = 0;
03293 ERROR3("Unsupported bitmap format in ReadPixel(32bpp)");
03294 break;
03295 }
03296
03297 return(Pix);
03298 }
03299
03300
03301
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311
03312
03313
03314
03315
03316
03317
03318
03319
03320
03321 INT32 CWxBitmap::ReturnPaletteIndexUsed( INT32 x, INT32 y )
03322 {
03323 RebuildXPEBitmap();
03324 ERROR3IF(BMInfo == NULL || BMBytes == NULL, "PlotPixel called on duff bitmap");
03325 ERROR3IF(x < 0 || y < 0 || x >= (INT32)GetWidth() || y >= (INT32)GetHeight(),
03326 "Illegal pixel position in CWxBitmap::ReadPixel");
03327
03328 BYTE *ScanlineStart = BMBytes + (y * ScanLineByteWidth);
03329
03330 INT32 PaletteIndex;
03331
03332 switch(BMInfo->bmiHeader.biBitCount)
03333 {
03334 case 1:
03335 {
03336 BYTE Temp = ScanlineStart[x >> 3];
03337 Temp &= 0x80 >> (x & 7);
03338 Temp = (Temp == 0) ? 0 : 1;
03339 PaletteIndex = Temp;
03340 }
03341 break;
03342
03343 case 4:
03344 {
03345 BYTE Temp = ScanlineStart[x / 2];
03346
03347
03348 if ((x & 1) == 0)
03349 Temp = (Temp >> 4) & 0x0f;
03350 else
03351 Temp &= 0x0f;
03352
03353 PaletteIndex = Temp;
03354 }
03355 break;
03356
03357 case 8:
03358 PaletteIndex = ScanlineStart[x];
03359 break;
03360
03361 default:
03362 PaletteIndex = -1;
03363 ERROR3( "Couldn't find the palette index" );
03364 break;
03365 }
03366
03367 return PaletteIndex;
03368 }
03369
03370
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380
03381
03382
03383
03384
03385
03386
03387
03388
03389
03390
03391
03392
03393
03394
03395
03396
03397 PixelGreyscale CWxBitmap::ReadPixelGreyscale(INT32 x, INT32 y)
03398 {
03399 RebuildXPEBitmap();
03400 ERROR3IF(BMInfo == NULL || BMBytes == NULL, "PlotPixel called on duff bitmap");
03401 ERROR3IF(x < 0 || y < 0 || x >= (INT32)GetWidth() || y >= (INT32)GetHeight(),
03402 "Illegal pixel position in CWxBitmap::ReadPixel");
03403
03404 BYTE *ScanlineStart = BMBytes + (y * ScanLineByteWidth);
03405 PixelGreyscale Pix;
03406
03407 switch(BMInfo->bmiHeader.biBitCount)
03408 {
03409 case 1:
03410 {
03411 BYTE Temp = ScanlineStart[x >> 3];
03412 Temp &= 0x80 >> (x & 7);
03413
03414 Pix = (Temp == 0) ? 0 : 255;
03415 }
03416 break;
03417
03418 case 4:
03419 {
03420 BYTE Temp = ScanlineStart[x / 2];
03421
03422
03423
03424 if ((x & 1) == 0)
03425 Temp = (Temp & 0xf0) | ((Temp & 0xf0) >> 4);
03426 else
03427 Temp = (Temp & 0x0f) | ((Temp & 0x0f) << 4);
03428
03429 Pix = Temp;
03430 }
03431 break;
03432
03433 case 8:
03434 Pix = ScanlineStart[x];
03435 break;
03436
03437 case 24:
03438 {
03439 double Temp;
03440
03441 x *= 3;
03442 Temp = 0.109 * (double) ScanlineStart[x++];
03443 Temp += 0.586 * (double) ScanlineStart[x++];
03444 Temp += 0.305 * (double) ScanlineStart[x];
03445
03446 Pix = (BYTE) Temp;
03447 }
03448 break;
03449
03450 case 32:
03451 {
03452 double Temp;
03453
03454 x *= 4;
03455 Temp = 0.109 * (double) ScanlineStart[x++];
03456 Temp += 0.586 * (double) ScanlineStart[x++];
03457 Temp += 0.305 * (double) ScanlineStart[x];
03458
03459 Pix = (BYTE) Temp;
03460 }
03461 break;
03462
03463 default:
03464 Pix = 0;
03465 ERROR3("Unsupported bitmap format in ReadPixel(32bpp)");
03466 break;
03467 }
03468
03469 return(Pix);
03470 }
03471
03472
03473
03474
03475
03476
03477
03478
03479
03480
03481
03482
03483
03484
03485
03486
03487
03488
03489 void CWxBitmap::CacheGeometry()
03490 {
03491 if (BMInfo)
03492 {
03493
03494
03495
03496
03497
03498
03499 LPBITMAPINFOHEADER pHeader = &(BMInfo->bmiHeader);
03500
03501 if (pHeader->biXPelsPerMeter != 0 || pHeader->biYPelsPerMeter != 0)
03502 {
03503 const double MaxSize = 0.84;
03504
03505 const double MaxWidth = MaxSize;
03506 const double Width = pHeader->biWidth;
03507 const double MinWidth = Width / M_MP_VAL;
03508 const double XDensity = pHeader->biXPelsPerMeter;
03509 const double RealWidth = Width / XDensity;
03510 INT32 XRecommended = (INT32)(96 * (M_MP_VAL / IN_MP_VAL));
03511
03512 const double MaxHeight = MaxSize;
03513 const double Height = pHeader->biHeight;
03514 const double MinHeight = Height / M_MP_VAL;
03515 const double YDensity = pHeader->biYPelsPerMeter;
03516 const double RealHeight = Height / YDensity;
03517 INT32 YRecommended = (INT32)(96 * (M_MP_VAL / IN_MP_VAL));
03518
03519 const double AspectRatio = XDensity / YDensity;
03520
03521 BOOL bIsTooBig = FALSE;
03522 BOOL bIsTooSmall = FALSE;
03523
03524
03525 if (pHeader->biXPelsPerMeter != 0)
03526 {
03527 if (RealWidth > MaxWidth)
03528 {
03529 XRecommended = (INT32)(pHeader->biWidth / MaxWidth);
03530 bIsTooBig = TRUE;
03531 }
03532 else if (RealWidth < MinWidth)
03533 {
03534 XRecommended = (INT32)(pHeader->biWidth / MinWidth);
03535 bIsTooSmall = TRUE;
03536 }
03537 }
03538
03539
03540 if (pHeader->biXPelsPerMeter != 0)
03541 {
03542 if (RealHeight > MaxHeight)
03543 {
03544 YRecommended = (INT32)(pHeader->biHeight / MaxHeight);
03545 bIsTooBig = TRUE;
03546 }
03547 else if (RealHeight < MinHeight)
03548 {
03549 YRecommended = (INT32)(pHeader->biHeight / MinHeight);
03550 bIsTooSmall = TRUE;
03551 }
03552 }
03553
03554
03555 if (bIsTooBig || bIsTooSmall)
03556 {
03557 if ((bIsTooBig && bIsTooSmall) || AspectRatio != 1.0)
03558 {
03559
03560 pHeader->biXPelsPerMeter = 0;
03561 pHeader->biYPelsPerMeter = 0;
03562 }
03563
03564
03565 else if ((bIsTooBig && XRecommended > YRecommended) ||
03566 (bIsTooSmall && XRecommended < YRecommended))
03567 {
03568 pHeader->biXPelsPerMeter = XRecommended;
03569 pHeader->biYPelsPerMeter = XRecommended;
03570 }
03571 else
03572 {
03573 pHeader->biXPelsPerMeter = YRecommended;
03574 pHeader->biYPelsPerMeter = YRecommended;
03575 }
03576 }
03577 }
03578
03579 ScanLineByteWidth = DIBUtil::ScanlineSize( pHeader->biWidth, pHeader->biBitCount );
03580 BitmapSize = ScanLineByteWidth*(pHeader->biHeight);
03581 }
03582 else
03583 {
03584 ScanLineByteWidth = 0;
03585 BitmapSize = 0;
03586 }
03587 }
03588
03589
03590
03591
03592
03593
03594
03595
03596
03597
03598
03599
03600
03601
03602
03603
03604
03605 INT32 CWxBitmap::operator==(const OILBitmap &Other)
03606 {
03607 CWxBitmap* OtherBmp = (CWxBitmap*)&Other;
03608 OtherBmp->RebuildXPEBitmap();
03609
03610 if (BMInfo == NULL || OtherBmp->BMInfo == NULL)
03611 return FALSE;
03612
03613
03614 if (BMBytes == NULL || OtherBmp->BMBytes == NULL)
03615 return FALSE;
03616
03617
03618
03619 if (BMInfo->bmiHeader.biSizeImage != OtherBmp->BMInfo->bmiHeader.biSizeImage ||
03620 BMInfo->bmiHeader.biWidth != OtherBmp->BMInfo->bmiHeader.biWidth ||
03621 BMInfo->bmiHeader.biHeight != OtherBmp->BMInfo->bmiHeader.biHeight ||
03622 BMInfo->bmiHeader.biBitCount != OtherBmp->BMInfo->bmiHeader.biBitCount ||
03623 BMInfo->bmiHeader.biClrUsed != OtherBmp->BMInfo->bmiHeader.biClrUsed ||
03624
03625 BMInfo->bmiHeader.biXPelsPerMeter != OtherBmp->BMInfo->bmiHeader.biXPelsPerMeter ||
03626 BMInfo->bmiHeader.biYPelsPerMeter != OtherBmp->BMInfo->bmiHeader.biYPelsPerMeter)
03627 {
03628 return FALSE;
03629 }
03630
03631
03632
03633
03634 if (BMInfo->bmiHeader.biBitCount <= 8)
03635 {
03636 INT32 NumCols = BMInfo->bmiHeader.biClrUsed;
03637 INT32* Pal = (INT32*)BMInfo->bmiColors;
03638 INT32* OtherPal = (INT32*)OtherBmp->BMInfo->bmiColors;
03639
03640
03641 if (memcmp(Pal, OtherPal, NumCols*4) != 0)
03642 return FALSE;
03643 }
03644
03645
03646
03647 INT32 Width = BMInfo->bmiHeader.biWidth;
03648 INT32 Height = BMInfo->bmiHeader.biHeight;
03649 INT32 Bpp = BMInfo->bmiHeader.biBitCount;
03650
03651
03652
03653
03654
03655
03656
03657
03658
03659
03660
03661
03662
03663
03664 INT32 ScanLineBytes = (Width * Bpp) / 8;
03665
03666 INT32 ExtraBits = 0;
03667 BYTE BitMask = 0;
03668
03669 if (Bpp < 8)
03670 {
03671
03672
03673 ExtraBits = (Width * Bpp) - (ScanLineBytes * 8);
03674
03675 const BYTE BitMaskArray[8] = {0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE};
03676 ERROR3IF (ExtraBits < 0 || ExtraBits > 7, "CWxBitmap::operator== - extraordinary ExtraBits");
03677 BitMask = BitMaskArray[ExtraBits];
03678 }
03679
03680
03681
03682 INT32 ScanAlign = DIBUtil::ScanlineSize(Width, Bpp);
03683
03684 BYTE* BmpData = BMBytes;
03685 BYTE* OtherBmpData = OtherBmp->BMBytes;
03686
03687 for (INT32 Scan = 0; Scan < Height; Scan++)
03688 {
03689
03690 if (memcmp(BmpData, OtherBmpData, ScanLineBytes) != 0)
03691 return FALSE;
03692
03693 if (ExtraBits > 0)
03694 {
03695
03696
03697
03698
03699
03700 BYTE BmpExtraByte = *(BmpData + ScanLineBytes) & BitMask;
03701 BYTE OtherExtraByte = *(OtherBmpData + ScanLineBytes) & BitMask;
03702
03703
03704
03705
03706 if (BmpExtraByte != OtherExtraByte)
03707 return FALSE;
03708 }
03709
03710 BmpData += ScanAlign;
03711 OtherBmpData += ScanAlign;
03712 }
03713
03714
03715 return TRUE;
03716 }
03717
03718
03719
03720
03721
03722
03723
03724
03725
03726
03727
03728
03729
03730
03731
03732 BOOL CWxBitmap::LoadBitmap(UINT32 BitmapResourceID)
03733 {
03734 wxBitmap * pBitmap=CamArtProvider::Get()->FindBitmap((ResourceID)BitmapResourceID);
03735 if (!pBitmap)
03736 return FALSE;
03737
03738 return CreateFromwxBitmap(pBitmap);
03739 }
03740
03741 BOOL CWxBitmap::CreateFromwxBitmap(wxBitmap * pBitmap)
03742 {
03743 wxImage i = pBitmap->ConvertToImage();
03744 return CreateFromwxImage(&i);
03745 }
03746
03747 BOOL CWxBitmap::CreateFromwxImage(wxImage * pImage)
03748 {
03749 LPBITMAPINFO bmInfo;
03750 LPBYTE bmBytes;
03751
03752 bmInfo = AllocDIB( pImage->GetWidth(), pImage->GetHeight(), 32, &bmBytes );
03753 if (!bmInfo || !bmBytes)
03754 return FALSE;
03755
03756 BMInfo=bmInfo;
03757 BMBytes=bmBytes;
03758
03759 INT32 dpi=96;
03760
03761 double xppm = ((double)dpi * 10000.0)/254.0;
03762 bmInfo->bmiHeader.biXPelsPerMeter = (INT32)(xppm + 0.5);
03763 bmInfo->bmiHeader.biYPelsPerMeter = bmInfo->bmiHeader.biXPelsPerMeter;
03764
03765 CacheGeometry();
03766
03767 unsigned char * pData=pImage->GetData();
03768 unsigned char * pAlpha=NULL;
03769 if (pImage->HasAlpha())
03770 pAlpha=pImage->GetAlpha();
03771
03772
03773 for (UINT32 YPos = 0; YPos < GetHeight(); YPos++)
03774 {
03775
03776 BYTE *ScanlineStart = BMBytes + ((GetHeight()-YPos-1) * ScanLineByteWidth);
03777 INT32 off=0;
03778
03779 for (UINT32 XPos = 0; XPos < GetWidth(); XPos++)
03780 {
03781 ScanlineStart[off++] = pData[2];
03782 ScanlineStart[off++] = pData[1];
03783 ScanlineStart[off++] = pData[0];
03784 pData+=(UINT_PTR)3;
03785 ScanlineStart[off++] = pAlpha?(255-*(pAlpha++)):0;
03786 }
03787 }
03788
03789 return TRUE;
03790 }
03791
03792
03793
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805
03806
03807
03808
03809 BOOL CWxBitmap::GetPaletteUsage(INT32 *UsageBuf)
03810 {
03811 ERROR3("CWxBitmap::GetPaletteUsage is unimplemented");
03812 return(FALSE);
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827
03828
03829
03830
03831
03832
03833
03834
03835
03836
03837
03838
03839
03840
03841
03842
03843
03844
03845
03846
03847
03848
03849
03850
03851
03852
03853
03854
03855
03856
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870
03871
03872
03873
03874
03875
03876
03877
03878
03879
03880 }
03881
03882 BOOL CWxBitmap::PrepareMask(INT32 PaletteEntry)
03883 {
03884 return FALSE;
03885 }
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895
03896
03897
03898
03899
03900
03901
03902
03903
03904
03905 BOOL CWxBitmap::GetScanlineMaskBits(INT32 ScanlineY, LPBYTE ScanlineBuf)
03906 {
03907 return TRUE;
03908 }
03909
03910 BOOL CWxBitmap::DestroyMask()
03911 {
03912 return FALSE;
03913 }
03914
03915
03916
03917
03918
03919
03920
03921
03922
03923
03924
03925
03926 void CWxBitmap::DeleteData(BOOL bResetToDefault)
03927 {
03928
03929
03930 FreeDIB( BMInfo, BMBytes );
03931 BMInfo = NULL;
03932 BMBytes = NULL;
03933
03934 if (bResetToDefault)
03935 {
03936 BMInfo = ((CWxBitmap*)OILBitmap::Default)->BMInfo;
03937 BMBytes = ((CWxBitmap*)OILBitmap::Default)->BMBytes;
03938
03939 ScanLineByteWidth = ((CWxBitmap*)OILBitmap::Default)->ScanLineByteWidth;
03940 BitmapSize = ((CWxBitmap*)OILBitmap::Default)->BitmapSize;
03941
03942 DestroyGreyscaleVersion();
03943 DestroyContonePalette();
03944 }
03945
03946 return;
03947 }
03948
03949
03950
03951
03952
03953
03954
03955
03956
03957
03958
03959
03960 BOOL CWxBitmap::HasBeenDeleted()
03961 {
03962 if (this == OILBitmap::Default)
03963 return FALSE;
03964
03965 ERROR3IF(OILBitmap::Default == NULL, "The default bitmap is NULL");
03966 if (OILBitmap::Default == NULL)
03967 return TRUE;
03968
03969
03970 return (BMBytes == ((CWxBitmap*)OILBitmap::Default)->BMBytes);
03971 }
03972
03973
03974
03975
03976
03977
03978
03979
03980
03981
03982
03983 void CWxBitmap::GenerateGreyscaleTable()
03984 {
03985 RebuildXPEBitmap();
03986
03987 if (GetBPP()>8)
03988 return;
03989 UINT32 bpp = GetBPP() ;
03990
03991 if (m_pGreyscaleTable != NULL)
03992 return;
03993
03994 m_pGreyscaleTable = new BYTE[1<<bpp];
03995 if (m_pGreyscaleTable == NULL)
03996 return;
03997
03998 for (INT32 i=0; i<1<<bpp; i++)
03999 {
04000 double R = BMInfo->bmiColors[i].rgbRed;
04001 double G = BMInfo->bmiColors[i].rgbGreen;
04002 double B = BMInfo->bmiColors[i].rgbBlue;
04003
04004 m_pGreyscaleTable[i] = BYTE((R * 0.305) + (G * 0.586) + (B * 0.109));
04005
04006 }
04007 }
04008
04009
04010
04011
04012
04013
04014
04015
04016
04017
04018
04019
04020
04021
04022
04023 BOOL CWxBitmap::IsBrowserPalette()
04024 {
04025
04026 if (GetBPP() != 8)
04027 return FALSE;
04028
04029 RebuildXPEBitmap();
04030 UINT32 PaletteEntries = GetNumPaletteEntries();
04031 if (PaletteEntries < 216)
04032 return FALSE;
04033
04034
04035 TRACEUSER( "Neville", wxT("Checking 216 colours\n") );
04036 BOOL found = FALSE;
04037 for (INT32 r = 0; r <= 100; r += 20)
04038 {
04039 for (INT32 g = 0; g <=100; g += 20)
04040 {
04041 for (INT32 b = 0; b <= 100; b += 20)
04042 {
04043 BYTE ra = BYTE((double(r)/100)*255.0);
04044 BYTE ga = BYTE((double(g)/100)*255.0);
04045 BYTE ba = BYTE((double(b)/100)*255.0);
04046
04047 for (UINT32 i = 0; i < PaletteEntries && !found; i++)
04048 {
04049 found = BMInfo->bmiColors[i].rgbRed == ra &&
04050 BMInfo->bmiColors[i].rgbGreen == ga &&
04051 BMInfo->bmiColors[i].rgbBlue == ba;
04052 }
04053
04054 if (!found)
04055 {
04056 TRACEUSER( "Neville", wxT("Colour not found - %d %d %d\n") ,r , g, b );
04057 return FALSE;
04058 }
04059 }
04060 }
04061 }
04062
04063
04064 TRACEUSER( "Neville", wxT("216 colours check finished\n") );
04065 return TRUE;
04066 }
04067
04068
04069
04070
04071
04072
04073
04074
04075
04076
04077
04078
04079
04080
04081
04082
04083 LPBITMAPINFO CWxBitmap::GetBitmapInfo()
04084 {
04085 RebuildXPEBitmap();
04086 return BMInfo;
04087 }
04088
04089
04090
04091
04092
04093
04094
04095
04096
04097
04098
04099
04100
04101
04102
04103
04104 LPRGBQUAD CWxBitmap::GetPaletteForBitmap()
04105 {
04106
04107 if (GetBPP() > 8)
04108 return NULL;
04109
04110 RebuildXPEBitmap();
04111 if (BMInfo == NULL)
04112 return NULL;
04113
04114
04115 return &(BMInfo->bmiColors[0]);
04116 }
04117
04118
04119
04120
04121
04122
04123
04124
04125
04126
04127
04128
04129
04130
04131
04132
04133 LPBITMAPINFOHEADER CWxBitmap::GetBitmapInfoHeader()
04134 {
04135 RebuildXPEBitmap();
04136 if (BMInfo == NULL)
04137 return NULL;
04138
04139
04140 return &BMInfo->bmiHeader;
04141 }
04142
04143
04144
04145
04146
04147
04148
04149
04150
04151
04152
04153
04154
04155
04156
04157
04158
04159
04160 BOOL CWxBitmap::ArePalettesTheSame(const LPLOGPALETTE pLogPalette, const INT32 TransColour)
04161 {
04162 ERROR2IF(pLogPalette == NULL,FALSE,"ArePalettesTheSame Bad LOGPALETTE param");
04163
04164
04165 UINT32 bpp = GetBPP();
04166 if (bpp != 8)
04167 return FALSE;
04168
04169 RebuildXPEBitmap();
04170
04171 LPRGBQUAD pPalette = GetPaletteForBitmap();
04172 if (pPalette == NULL)
04173 return FALSE;
04174
04175 UINT32 PaletteEntries = GetNumPaletteEntries();
04176 if (PaletteEntries != pLogPalette->palNumEntries)
04177 return FALSE;
04178
04179
04180 BOOL PaletteOk = TRUE;
04181 for (INT32 i = 0; i < pLogPalette->palNumEntries; i++)
04182 {
04183
04184 if (i == TransColour)
04185 {
04186 if (pPalette[i].rgbRed != 0xFF &&
04187 pPalette[i].rgbGreen != 0xFF &&
04188 pPalette[i].rgbBlue != 0xFF)
04189 {
04190 PaletteOk = FALSE;
04191 break;
04192 }
04193 }
04194 else if (pPalette[i].rgbRed != pLogPalette->palPalEntry[i].peRed &&
04195 pPalette[i].rgbGreen != pLogPalette->palPalEntry[i].peGreen &&
04196 pPalette[i].rgbBlue != pLogPalette->palPalEntry[i].peBlue)
04197 {
04198 PaletteOk = FALSE;
04199 break;
04200 }
04201 }
04202
04203 return PaletteOk;
04204 }
04205
04206
04207
04208
04209
04210
04211
04212
04213
04214
04215
04216
04217
04218
04219
04220
04221 void CWxBitmap::ExtractBitsAndInfo(LPBYTE* ppBytes, LPBITMAPINFO* ppInfo)
04222 {
04223 RebuildXPEBitmap();
04224 *ppBytes = BMBytes;
04225 *ppInfo = BMInfo;
04226
04227 BMBytes = NULL;
04228 BMInfo = NULL;
04229 }
04230
04231
04232
04233
04234
04235
04236
04237
04238
04239
04240
04241
04242
04243
04244
04245
04246 void CWxBitmap::ReplaceBitmap(LPBYTE pBytes, LPBITMAPINFO pInfo)
04247 {
04248 if (IsDefaultBitmap())
04249 {
04250 ERROR2RAW("ReplaceBitmap asked to replace the default bitmap!");
04251 return;
04252 }
04253
04254 if (pBytes==NULL && pInfo==NULL)
04255 {
04256 ERROR2RAW("Call to ReplaceBitmap with bad parameters");
04257 return;
04258 }
04259
04260
04261 FreeDIB( BMInfo, BMBytes );
04262 DestroyGreyscaleVersion();
04263 DestroyContonePalette();
04264
04265
04266 BMInfo = pInfo;
04267 BMBytes = pBytes;
04268
04269
04270 CacheGeometry();
04271 }
04272
04273
04274 void CWxBitmap::CopyFullyTransparentFrom(OILBitmap* pBitmap)
04275 {
04276 if (GetWidth() != pBitmap->GetWidth() ||
04277 GetHeight() != pBitmap->GetHeight() ||
04278 GetBPP() != 32 ||
04279 pBitmap->GetBPP() != 32)
04280 {
04281 ERROR3("Incompatible bitmaps passed to CopyFullyTransparentFrom");
04282 return;
04283 }
04284
04285
04286 UINT32* pMask = (UINT32*)(pBitmap->GetBitmapBits());
04287 UINT32* pDest = (UINT32*)GetBitmapBits();
04288
04289
04290 for (UINT32 j=0; j < pBitmap->GetHeight(); j++)
04291 {
04292 for (UINT32 i=0; i < pBitmap->GetWidth(); i++)
04293 {
04294
04295
04296 if (*pMask == 0xFF000000)
04297 *pDest = 0xFF000000;
04298
04299
04300 pMask++;
04301 pDest++;
04302 }
04303 }
04304 }