123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944 |
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Copyright 2016 RWS Inc, All Rights Reserved
- //
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of version 2 of the GNU General Public License as published by
- // the Free Software Foundation
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License along
- // with this program; if not, write to the Free Software Foundation, Inc.,
- // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- //
- //////////////////////////////////////////////////////////////////////
- //
- // IMAGECON.CPP
- //
- // Created on 09/28/95 BRH
- // Implemented on 09/28/95 BRH
- //
- // 09/28/95 BRH Standard conversion functions for the standard
- // image types. The two main standards are 8 and 24
- // bit images. The standard converters are explained
- // below
- //
- // 11/03/95 BRH Added support for RPal's new sPalEntrySize. Any
- // conversion that changes the palette will also
- // update this variable.
- //
- // 11/06/95 BRH Fixed the ConvertToSCREEN8_888 to use the proper
- // 24-bit palette entries rather than the 32-bit
- // that it was using.
- //
- // 11/07/95 JMI Changed all occurrences of RGBQUAD to IM_RGBQUAD &
- // RGBTRIPLE to IM_RGBTRIPLE.
- //
- // 11/08/95 BRH Added several direct conversions to BMP8 and BMP24.
- // Previously we had BMP8 and BMP24 as our two base
- // types which then were converted to SCREEN8_xxx formats
- // and others. By providing a few more direct conversions
- // I can then provide almost any other conversion by
- // calling two conversion functions, one from the current
- // to BMP8 and then from BMP8 to the new format. The
- // only conversions not supported are high color or
- // true color images being converted to palette images.
- //
- // 11/15/95 BRH Change the conversion routines that deal with palettes
- // so that the images keep the original RPal object in
- // their pPalette pointers when the are converted.
- // Previously the conversion routines detached the
- // palette from the RImage and then created a new palette
- // and attached that to the RImage. This causes trouble
- // if there are other external pointers to the same RPal,
- // for example if several images use the same palette we
- // don't want to throw the palette out. Now the image
- // keeps the same RPal object and only the palette's data
- // is discarded during the conversion.
- //
- // 11/20/95 BRH Finished up all of the cross conversions between formats
- // using intermediate BMP8 or BMP24 translations when necessary.
- // Currently any standard format can be converted to any other
- // standard format with the exception that 32, 24, or 16 bit
- // images cannot be converted to any of the 8 bit formats due
- // to the lack of a good color reduction algorithm.
- //
- // 01/15/96 JMI Changed the array of conversion functions to a dynamic
- // linking mechanism of ConvertTo and ConvertFrom function
- // pointers so that new conversion functions can be added in
- // .cpp files other than imagecon.cpp.
- //
- // 01/16/96 BRH Added calls to RImage::GetPitch(width,depth) to calculate
- // the 128-bit aligned pitch for converted image types.
- // previously, several of the conversion functions forgot
- // to change the pitch for the new format.
- //
- // 01/19/96 BRH Fixed a bug in creating new buffers. Most calls were
- // incorrectly using width*height*(depth/8) where they should
- // have been using pitch instead of width.
- //
- // 02/27/95 BRH Changed over from using DYNALINK to the RImageSpecialFunc
- // class for Conversion functions. The new class is based on
- // the same concept as DYNALINK but is specialized for RImage
- // in that it supports 6 special function types for conversion
- // to/from, load/save, and alloc/delete. I moved the instantiation
- // of the static arrays from imagecon.cpp to image.cpp since
- // it now instantiates 6 arrays, 4 of which are not conversion
- // related. Then I changed the calls to LINKLATE macros (DYNALINK)
- // to IMAGELINKLATE macros (RImageSpecialFunc).
- //
- // 07/22/96 JMI Added ConvertFromBMP8RLE to allow LoadDib to load RLE8
- // compressed DIBs. BMP8RLE format can be used as any other
- // image format. Will implement ConvertToBMP8RLE soon.
- //
- // 07/23/96 JMI Added ConvertToBMP8RLE to allow one to convert into
- // BMP8RLE (RLE8 Windows' bitmap compressed format). The convert
- // flips upside down as it compresses making it official
- // as far as BMP files go. SaveDib is aware of this use of
- // RLE8 and can save these preserving compression.
- // Also, made ConvertFromBMP8RLE flip the image so you get
- // a DIB that is upside down as far as DIBs go, but right side
- // up to the naked eye. This is functionality was implemented
- // since LoadDib does this as well.
- //
- // 08/04/96 MJR Commented-out the "pImage" parameter to ConvertNoSupport()
- // to avoid compiler warning about "unused variable".
- // Also modified ConvertToSystem() to use WIN32 instead of
- // _WINDOWS and to use MAC instead of _MAC. However, note that
- // ConvertToSystem() still does nothing on the mac.
- //
- // 09/04/96 JMI Added BMP1 IMAGELINKLATE's and corresponding ConvertToBMP1()
- // and ConvertFromBMP1(). BMP8 is, as usual, the only type
- // convertible to BMP1.
- //
- // 10/10/96 JMI ConvertToBMP24() was not checking for error return from
- // CreateData() and so it was crashing when memory was
- // low.
- //
- // 10/30/96 JMI Changed:
- // Old label: New label:
- // ========= =========
- // RImage RImage
- // RPal RPal
- // ULONG ulType RImage::Type ulType
- //
- // Removed #include of "imagetyp.h" b/c it has been obsoleted.
- // Removed #include of "imagecon.h" b/c all it does is include
- // image.h and then redeclare RImage (now RImage anyway) and
- // replaced with #include of image.h.
- //
- // 11/01/96 JMI Changed all members of image to be preceded by m_ (e.g.,
- // sDepth to m_sDepth). Changed all position members (i.e.,
- // lWidth, lHeight, lBufferWidth, lBufferHeight, lXPos, & lYPos)
- // to be shorts (i.e., m_sWidth, m_sHeight, m_sBufferWidth,
- // m_sBufferHeight, m_sXPos, m_sYPos). Changed ulType to
- // m_type and ulDestinationType to m_typeDestination.
- //
- // 11/06/96 MJR Added "RImage::: before many instances of BMP8, BMP24, etc.
- // This was suddenly required because the IMAGELINKLATE macro
- // no longer used the "using" syntax which had, as a side-effect,
- // allowed the use of the enums without a preceeding "RImage::".
- //
- // 11/08/96 JMI Added more "RImage::"s where necessary in the #ifdef WIN32
- // block.
- //
- // 11/08/96 JMI Changed reference of BMP8RLE to RImage::BMP8RLE in an ASSERT.
- //
- // Standard Converters:
- //
- // Buffer Conversions:
- //
- // BMP8 (8-bit buffer 32-bit color pal) -> 16-bit buffer (555)
- // BMP8 (8-bit buffer 32-bit color pal) -> 16-bit buffer (565)
- // BMP8 (8-bit buffer 32-bit color pal) -> 24-bit buffer (888) RGB
- // BMP8 (8-bit buffer 32-bit color pal) -> 32-bit buffer (8888) ARGB
- // BMP24 (24-bit buffer) -> 16-bit buffer (555)
- // BMP24 (24-bit buffer) -> 16-bit buffer (565)
- // BMP24 (24-bit buffer) -> 32-bit buffer (8888) ARGB
- //
- // Palette Conversions:
- //
- // BMP8 (IM_RGBQUAD) -> 555 Palette
- // BMP8 (IM_RGBQUAD) -> 565 Palette
- // BMP8 (IM_RGBQUAD) -> 888 Palette
- // BMP8 (IM_RGBQUAD) -> SYSTEM Palette (for setting colors on a platform
- // basis) Windows = IM_RGBQUAD, Mac = Mac System Pal
- //
- //
- //////////////////////////////////////////////////////////////////////
- #include <stdlib.h>
- #include <string.h>
- #include "Image.h"
- //////////////////////////////////////////////////////////////////////
- // Prototypes.
- //////////////////////////////////////////////////////////////////////
- short ConvertNoSupport(RImage* pImage);
- short ConvertToBMP8(RImage* pImage);
- short ConvertToBMP24(RImage* pImage);
- short ConvertToSystem(RImage* pImage);
- short ConvertToSCREEN8_555(RImage* pImage);
- short ConvertToSCREEN8_565(RImage* pImage);
- short ConvertToSCREEN8_888(RImage* pImage);
- short ConvertToSCREEN16_555(RImage* pImage);
- short ConvertToSCREEN16_565(RImage* pImage);
- short ConvertToSCREEN24_RGB(RImage* pImage);
- short ConvertToSCREEN32_ARGB(RImage* pImage);
- IMAGELINKLATE(BMP8, ConvertToBMP8, NULL, NULL, NULL, NULL, NULL);
- IMAGELINKLATE(SYSTEM8, ConvertToSystem, NULL, NULL, NULL, NULL, NULL);
- IMAGELINKLATE(SCREEN8_555, ConvertToSCREEN8_555, NULL, NULL, NULL, NULL, NULL);
- IMAGELINKLATE(SCREEN8_565, ConvertToSCREEN8_565, NULL, NULL, NULL, NULL, NULL);
- IMAGELINKLATE(SCREEN8_888, ConvertToSCREEN8_888, NULL, NULL, NULL, NULL, NULL);
- IMAGELINKLATE(BMP24, ConvertToBMP24, NULL, NULL, NULL, NULL, NULL);
- IMAGELINKLATE(SCREEN16_555, ConvertToSCREEN16_555, NULL, NULL, NULL, NULL, NULL);
- IMAGELINKLATE(SCREEN16_565, ConvertToSCREEN16_565, NULL, NULL, NULL, NULL, NULL);
- IMAGELINKLATE(SCREEN24_RGB, ConvertToSCREEN24_RGB, NULL, NULL, NULL, NULL, NULL);
- IMAGELINKLATE(SCREEN32_ARGB, ConvertToSCREEN32_ARGB, NULL, NULL, NULL, NULL, NULL);
- //////////////////////////////////////////////////////////////////////
- // More non-standard, always supported types:
- //////////////////////////////////////////////////////////////////////
- // BMP compression format (BMP8RLE).
- short ConvertToBMP8RLE(RImage* pImage);
- short ConvertFromBMP8RLE(RImage* pImage);
- // Link in conversion functions.
- IMAGELINKLATE(BMP8RLE, ConvertToBMP8RLE, ConvertFromBMP8RLE, NULL, NULL, NULL, NULL);
- // Monochrome BMP (BMP1).
- short ConvertToBMP1(RImage* pImage);
- short ConvertFromBMP1(RImage* pImage);
- // Link in conversion functions.
- IMAGELINKLATE(BMP1, ConvertToBMP1, ConvertFromBMP1, NULL, NULL, NULL, NULL);
- //////////////////////////////////////////////////////////////////////
- //
- // ConvertNoSupport:
- //
- // Catch function in case somebody passes in a format that is not
- // supported. This function will just return RImage::NOT_SUPPORTED
- //
- //////////////////////////////////////////////////////////////////////
- short ConvertNoSupport(RImage* /*pImage*/)
- {
- TRACE("RImage::Convert - Conversion not supported - Invalid image type\n");
- return RImage::NOT_SUPPORTED;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // ConvertToBMP8
- //
- // For now this conversion is not supported. RImage::BMP8 is a standard
- // load format so it is not apparent at this time why one couldn't
- // simply use the load function to obtain a RImage::BMP8 format. We don't
- // see the need to convert from one of the other formats into RImage::BMP8
- // but if it becomes necessary or convenient then it can be supported
- //
- //////////////////////////////////////////////////////////////////////
- short ConvertToBMP8(RImage* pImage)
- {
- short sReturn;
- switch (pImage->m_type)
- {
- case RImage::BMP8:
- {
- sReturn = RImage::BMP8;
- break;
- }
- case RImage::SYSTEM8:
- {
- #ifdef _WINDOWS
- pImage->m_type = RImage::BMP8;
- pImage->m_pPalette->m_type = RPal::PDIB;
- return RImage::BMP8;
- #endif
- break;
- }
- case RImage::SCREEN8_555:
- {
- // Make a copy of the original palette
- RPal* p555Pal = new RPal();
- *p555Pal = *pImage->m_pPalette;
- // Detach the original palette data from the Image's palette
- p555Pal->m_pData = pImage->m_pPalette->DetachData();
- // Create new palette data for the pImage
- pImage->m_pPalette->CreateData((p555Pal->m_sStartIndex + p555Pal->m_sNumEntries) * RPal::GetPalEntrySize(RPal::PDIB));
- pImage->m_pPalette->m_type = RPal::PDIB;
- pImage->m_pPalette->m_sPalEntrySize = RPal::GetPalEntrySize(RPal::PDIB);
- USHORT* usp555 = (USHORT*) p555Pal->m_pData;
- ULONG* ulpDib = (ULONG*) pImage->m_pPalette->m_pData;
- short i;
-
- // The 555 viewed as USHORT as xR5|G5|B5
- // viewed as 2 BYTES G3|B5|x|R5|G2
- // The DIB viewed as ULONG is Reserved|R|G|B
- // viewed as 4 BYTES B|G|R|Reserved
- for (i = p555Pal->m_sStartIndex; i < p555Pal->m_sStartIndex + p555Pal->m_sNumEntries; i++)
- ulpDib[i] = (ULONG) (((usp555[i] & 0x7c00) << 9) + // Red
- ((usp555[i] & 0x03e0) << 6) + // Green
- ((usp555[i] & 0x001f) << 3)); // Blue
- delete p555Pal;
- pImage->m_type = RImage::BMP8;
- sReturn = RImage::BMP8;
- break;
- }
- case RImage::SCREEN8_565:
- {
- // Make a copy of the original palette
- RPal* p565Pal = new RPal();
- *p565Pal = *pImage->m_pPalette;
- // Detach the original palette data from the Image's palette
- p565Pal->m_pData = pImage->m_pPalette->DetachData();
- // Create new palette data for the pImage
- pImage->m_pPalette->CreateData((p565Pal->m_sStartIndex + p565Pal->m_sNumEntries) * RPal::GetPalEntrySize(RPal::PDIB));
- pImage->m_pPalette->m_type = RPal::PDIB;
- pImage->m_pPalette->m_sPalEntrySize = RPal::GetPalEntrySize(RPal::PDIB);
- USHORT* usp565 = (USHORT*) p565Pal->m_pData;
- ULONG* ulpDib = (ULONG*) pImage->m_pPalette->m_pData;
- short i;
-
- // The 565 when viewed as USHORT R5|G6|B5
- // viewed as 2 BYTES G3|B5|R5|G3
- // The DIB when viewed as ULONG Reserved|R|G|B
- // viewed as 4 BYTES B|G|R|Reserved
- for (i = p565Pal->m_sStartIndex; i < p565Pal->m_sStartIndex + p565Pal->m_sNumEntries; i++)
- ulpDib[i] = (ULONG) (((usp565[i] & 0xf800) << 8) + // Red
- ((usp565[i] & 0x07e0) << 5) + // Green
- ((usp565[i] & 0x001f) << 3)); // Blue
- delete p565Pal;
- pImage->m_type = RImage::BMP8;
- sReturn = RImage::BMP8;
- break;
- }
- case RImage::SCREEN8_888:
- {
- // Make a copy of the original palette
- RPal* p888Pal = new RPal();
- *p888Pal = *pImage->m_pPalette;
- // Detach the original palette data form the Image's palette
- p888Pal->m_pData = pImage->m_pPalette->DetachData();
- // Create new palette data for the pImage
- pImage->m_pPalette->CreateData((p888Pal->m_sStartIndex + p888Pal->m_sNumEntries) * sizeof(IM_RGBQUAD));
- pImage->m_pPalette->m_type = RPal::PDIB;
- pImage->m_pPalette->m_sPalEntrySize = RPal::GetPalEntrySize(RPal::PDIB);
- IM_RGBTRIPLE* tp888 = (IM_RGBTRIPLE*) p888Pal->m_pData;
- IM_RGBQUAD* qpDib = (IM_RGBQUAD*) pImage->m_pPalette->m_pData;
-
- short i;
- // The DIB format when viewed as a IM_RGBQUAD = B|G|R|Reserved
- // The 888 palette viewed as IM_RGBTRIPLE B|G|R
- for (i = p888Pal->m_sStartIndex; i < p888Pal->m_sStartIndex + p888Pal->m_sNumEntries; i++)
- {
- qpDib[i].rgbBlue = tp888[i].rgbtBlue;
- qpDib[i].rgbGreen = tp888[i].rgbtGreen;
- qpDib[i].rgbRed = tp888[i].rgbtRed;
- qpDib[i].rgbReserved = 0;
- }
- delete p888Pal;
- pImage->m_type = RImage::BMP8;
- sReturn = RImage::BMP8;
- break;
- }
-
- default:
- {
- sReturn = RImage::NOT_SUPPORTED;
- break;
- }
- }
- return sReturn;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // ConvertToBMP24
- //
- // For now this conversion is not supported. BMP24 is a standard
- // load format which would normally either be used as BMP24 after
- // the load or converted to one of the other image formats.
- //
- //////////////////////////////////////////////////////////////////////
- short ConvertToBMP24(RImage* pImage)
- {
- short sReturn;
- switch (pImage->m_type)
- {
- case RImage::BMP24:
- {
- sReturn = RImage::BMP24;
- break;
- }
- case RImage::BMP8:
- {
- ConvertToSCREEN24_RGB(pImage);
- pImage->m_type = RImage::BMP24;
- sReturn = RImage::BMP24;
- break;
- }
- case RImage::SCREEN8_555:
- case RImage::SCREEN8_565:
- case RImage::SCREEN8_888:
- case RImage::SYSTEM8:
- {
- if (ConvertToBMP8(pImage) == RImage::BMP8)
- sReturn = ConvertToBMP24(pImage);
- else
- {
- TRACE("RImage::Convert - BMP24: Intermediate RImage::BMP8 translation error\n");
- sReturn = RImage::NOT_SUPPORTED;
- }
- break;
- }
- case RImage::SCREEN24_RGB:
- {
- pImage->m_type = RImage::BMP24;
- sReturn = RImage::BMP24;
- break;
- }
- case RImage::SCREEN32_ARGB:
- {
- long r, c, height, width, sPitch;
- // Make sure that we copy the whole thing even if the
- // height and width are negative values
- height = labs((long)pImage->m_sHeight);
- width = labs((long)pImage->m_sWidth);
- sPitch = pImage->m_lPitch;
- // Set a pointer to the 32-bit buffer before detaching
- ULONG* ulp32 = (ULONG*) pImage->m_pData;
- // Detach the 32-bit buffer from the Image
- void* pDetachedMem = pImage->DetachData();
- // Create a new 24-bit buffer and set a pointer to the data
- pImage->m_sDepth = 24;
- pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
- if (pImage->CreateData(pImage->m_lPitch * (long)pImage->m_sHeight) == 0)
- {
- UCHAR* ucp24 = (UCHAR*) pImage->m_pData;
- long sPitchWidth = sPitch / 4;
- for (r = 0; r < height; r++)
- for (c = 0; c < width; c++)
- {
- ULONG ulPixel = ulp32[r*sPitchWidth + c];
- ucp24[r*pImage->m_lPitch + 3*c+0] = (UCHAR) (ulPixel & 0x000000ff); // Red
- ucp24[r*pImage->m_lPitch + 3*c+1] = (UCHAR) ((ulPixel & 0x0000ff00) >> 8); // Green
- ucp24[r*pImage->m_lPitch + 3*c+2] = (UCHAR) ((ulPixel & 0x00ff0000) >> 16);// Blue
- }
-
- RImage::DestroyDetachedData(&pDetachedMem);
- pImage->m_type = RImage::BMP24;
- sReturn = RImage::BMP24;
- }
- else
- {
- // Restore memory.
- pImage->m_pMem = (UCHAR*)pDetachedMem;
- pImage->m_pData = (UCHAR*)ulp32;
- TRACE("ConvertToBMP24(): CreateData() failed.\n");
- // Return old type.
- sReturn = (short)pImage->m_type;
- }
- break;
- }
- case RImage::SCREEN16_555:
- {
- long r, c, height, width, sPitch;
- // Make sure that we copy the whole thing even if the
- // height and width are negative values
- height = labs((long)pImage->m_sHeight);
- width = labs((long)pImage->m_sWidth);
- sPitch = pImage->m_lPitch;
- // Set up a pointer to the 16-bit buffer before detaching
- USHORT* usp16 = (USHORT*) pImage->m_pData;
- // Detach old 16-bit buffer from the Image
- void* pDetachedMem = pImage->DetachData();
- // Create a new 24-bit buffer and set a pointer to the data
- pImage->m_sDepth = 24;
- pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
- pImage->CreateData(pImage->m_lPitch * (long)pImage->m_sHeight);
- UCHAR* ucp24 = (UCHAR*) pImage->m_pData;
- long sPitchWidth = sPitch/2;
- for (r = 0; r < height; r++)
- for (c = 0; c < width; c++)
- {
- USHORT usPixel = usp16[r*sPitchWidth + c];
- ucp24[r*pImage->m_lPitch + 3*c+2] = (UCHAR) ((usPixel & 0x7c00) >> 7); // Red
- ucp24[r*pImage->m_lPitch + 3*c+1] = (UCHAR) ((usPixel & 0x03e0) >> 2); // Green
- ucp24[r*pImage->m_lPitch + 3*c+0] = (UCHAR) ((usPixel & 0x001f) << 3); // Blue
- }
-
- RImage::DestroyDetachedData(&pDetachedMem);
- pImage->m_type = RImage::BMP24;
- sReturn = RImage::BMP24;
- break;
- }
- case RImage::SCREEN16_565:
- {
- long r, c, height, width, sPitch;
- // Make sure that we copy the whole thing even if the
- // height and width are negative values
- height = labs((long)pImage->m_sHeight);
- width = labs((long)pImage->m_sWidth);
- sPitch = pImage->m_lPitch;
- // Set a pointer to the 16-bit buffer before detaching
- USHORT* usp16 = (USHORT*) pImage->m_pData;
- // Detach the 16-bit buffer from the Image
- void* pDetachedMem = pImage->DetachData();
- // Create a new 24-bit buffer and set a pointer to the data
- pImage->m_sDepth = 24;
- pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
- pImage->CreateData(pImage->m_lPitch * (long)pImage->m_sHeight);
- UCHAR* ucp24 = (UCHAR*) pImage->m_pData;
- long sPitchWidth = sPitch/2;
- for (r = 0; r < height; r++)
- for (c = 0; c < width; c++)
- {
- USHORT usPixel = usp16[r*sPitchWidth + c];
- ucp24[r*pImage->m_lPitch + 3*c+2] = (UCHAR) ((usPixel & 0xf800) >> 8); // Red
- ucp24[r*pImage->m_lPitch + 3*c+1] = (UCHAR) ((usPixel & 0x07e0) >> 3); // Green
- ucp24[r*pImage->m_lPitch + 3*c+0] = (UCHAR) ((usPixel & 0x001f) << 3); // Blue
- }
- RImage::DestroyDetachedData(&pDetachedMem);
- pImage->m_type = RImage::BMP24;
- sReturn = RImage::BMP24;
- break;
- }
- default:
- {
- sReturn = RImage::NOT_SUPPORTED;
- break;
- }
- }
- return sReturn;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // ConvertToSystem
- //
- // This convert function will depened on what platform it is complied
- // on. Our standard load formats are Windows BMP. This function for
- // Windows will only change the type from RImage::BMP8 to RImage::SYSTEM8. On a Mac
- // it would convert the palette from IM_RGBQUAD to the Mac's system
- // palette.
- //
- //////////////////////////////////////////////////////////////////////
- short ConvertToSystem(RImage* pImage)
- {
- short sReturn = RImage::NOT_SUPPORTED;
- #ifdef WIN32
- switch (pImage->m_type)
- {
- case RImage::SYSTEM8:
- {
- sReturn = RImage::SYSTEM8;
- break;
- }
-
- case RImage::BMP8:
- {
- pImage->m_type = RImage::SYSTEM8;
- pImage->m_pPalette->m_type = RPal::PSYS;
- sReturn = RImage::SYSTEM8;
- break;
- }
- case RImage::SCREEN8_555:
- case RImage::SCREEN8_565:
- case RImage::SCREEN8_888:
- {
- if (ConvertToBMP8(pImage) == RImage::BMP8)
- sReturn = ConvertToSystem(pImage);
- else
- {
- TRACE("RImage::Convert - RImage::SYSTEM8: Intermediate RImage::BMP8 translation error\n");
- sReturn = RImage::NOT_SUPPORTED;
- }
- break;
- }
- default:
- {
- sReturn = RImage::NOT_SUPPORTED;
- break;
- }
- }
- #endif
- return sReturn;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // ConvertToSCREEN8_555
- //
- // Converts from RImage::BMP8 to SCREEN8_555 which means that it transforms
- // the palette entries from IM_RGBQUAD to the 555 "Screen Format" palette
- //
- //////////////////////////////////////////////////////////////////////
- short ConvertToSCREEN8_555(RImage* pImage)
- {
- short sReturn;
- switch (pImage->m_type)
- {
- case RImage::SCREEN8_555:
- {
- sReturn = RImage::SCREEN8_555;
- break;
- }
- case RImage::BMP8:
- {
- // Make a copy of the original palette
- RPal* pDibPal = new RPal();
- *pDibPal = *pImage->m_pPalette;
- // Detach the original palette data from the Image's palette
- pDibPal->m_pData = pImage->m_pPalette->DetachData();
- // Create new palette data for the Image
- pImage->m_pPalette->CreateData((pDibPal->m_sStartIndex + pDibPal->m_sNumEntries) * 2);
- pImage->m_pPalette->m_type = RPal::P555;
- pImage->m_pPalette->m_sPalEntrySize = RPal::GetPalEntrySize(RPal::P555);
- ULONG* ulpDib = (ULONG*) pDibPal->m_pData;
- USHORT* usp555 = (USHORT*) pImage->m_pPalette->m_pData;
- short i;
-
- // The DIB format when viewed as a ULONG is Reserved|R|G|B
- // when viewed as 4 BYTES is B|G|R|Reserved
- // Converting to 555 viewed as USHORT as xR5|G5|B5
- // viewed as 2 BYTES G3|B5|x|R5|G2
- for (i = pDibPal->m_sStartIndex; i < pDibPal->m_sStartIndex + pDibPal->m_sNumEntries; i++)
- usp555[i] = (USHORT) (((ulpDib[i] & 0x00f80000) >> 9) + // Red
- ((ulpDib[i] & 0x0000f800) >> 6) + // Green
- ((ulpDib[i] & 0x000000f8) >> 3)); // Blue
- delete pDibPal;
- pImage->m_type = RImage::SCREEN8_555;
- sReturn = RImage::SCREEN8_555;
- break;
- }
- case RImage::SYSTEM8:
- case RImage::SCREEN8_565:
- case RImage::SCREEN8_888:
- {
- if (ConvertToBMP8(pImage) == RImage::BMP8)
- sReturn = ConvertToSCREEN8_555(pImage);
- else
- {
- TRACE("RImage::Convert - SCREEN8_555 Intermediate RImage::BMP8 translation error\n");
- sReturn = RImage::NOT_SUPPORTED;
- }
- }
- default:
- {
- sReturn = RImage::NOT_SUPPORTED;
- break;
- }
- }
- return sReturn;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // ConvertToSCREEN8_565
- //
- // Converts from RImage::BMP8 to SCREEN8_565 which means that it transforms
- // the palette entries from IM_RGBQUAD to the 565 "Screen Format" palette
- //
- //////////////////////////////////////////////////////////////////////
- short ConvertToSCREEN8_565(RImage* pImage)
- {
- short sReturn;
- switch (pImage->m_type)
- {
- case RImage::SCREEN8_565:
- {
- sReturn = RImage::SCREEN8_565;
- break;
- }
- case RImage::BMP8:
- {
- // Make a copy of the original palette
- RPal* pDibPal = new RPal();
- *pDibPal = *pImage->m_pPalette;
- // Detach the original palette data from the Image's palette
- pDibPal->m_pData = pImage->m_pPalette->DetachData();
- // Create new palette data for the pImage
- pImage->m_pPalette->CreateData((pDibPal->m_sStartIndex + pDibPal->m_sNumEntries) * 2);
- pImage->m_pPalette->m_type = RPal::P565;
- pImage->m_pPalette->m_sPalEntrySize = RPal::GetPalEntrySize(RPal::P565);
- ULONG* ulpDib = (ULONG*) pDibPal->m_pData;
- USHORT* usp565 = (USHORT*) pImage->m_pPalette->m_pData;
- short i;
-
- // The DIB format when viewed as a ULONG is Reserved|R|G|B
- // when viewed as 4 BYTES is B|G|R|Reserved
- // Converting to 565 viewed as USHORT as R5|G6|B5
- // viewed as 2 BYTES G3|B5|R5|G3
- for (i = pDibPal->m_sStartIndex; i < pDibPal->m_sStartIndex + pDibPal->m_sNumEntries; i++)
- usp565[i] = (USHORT) (((ulpDib[i] & 0x00f80000) >> 8) + // Red
- ((ulpDib[i] & 0x0000fc00) >> 5) + // Green
- ((ulpDib[i] & 0x000000f8) >> 3)); // Blue
- delete pDibPal;
- pImage->m_type = RImage::SCREEN8_565;
- sReturn = RImage::SCREEN8_565;
- break;
- }
- case RImage::SYSTEM8:
- case RImage::SCREEN8_555:
- case RImage::SCREEN8_888:
- {
- if (ConvertToBMP8(pImage) == RImage::BMP8)
- sReturn = ConvertToSCREEN8_565(pImage);
- else
- {
- TRACE("RImage::Convert - SCREEN8_565 Intermediate RImage::BMP8 translation error\n");
- sReturn = RImage::NOT_SUPPORTED;
- }
- break;
- }
- default:
- {
- sReturn = RImage::NOT_SUPPORTED;
- break;
- }
-
- }
- return sReturn;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // ConvertToSCREEN8_888
- //
- // Converts from RImage::BMP8 to SCREEN8_888 which means that it transforms
- // the palette entries from IM_RGBQUAD to the 888 "Screen Format" palette
- //
- // The normal RImage::BMP8 DIB palette
- // when viewed as ULONG is Reserved|R|G|B
- //
- // And the screen format is the same, so just change the image type
- //
- //////////////////////////////////////////////////////////////////////
- short ConvertToSCREEN8_888(RImage* pImage)
- {
- short sReturn;
- switch(pImage->m_type)
- {
- case RImage::SCREEN8_888:
- {
- sReturn = RImage::SCREEN8_888;
- break;
- }
- case RImage::BMP8:
- {
- RPal* pDibPal = new RPal();
- *pDibPal = *pImage->m_pPalette;
- // Detach the original palette data from the Image's palette
- pDibPal->m_pData = pImage->m_pPalette->DetachData();
- // Create new palette data for the pImage
- pImage->m_pPalette->CreateData((pDibPal->m_sStartIndex + pDibPal->m_sNumEntries) * sizeof(IM_RGBTRIPLE));
- pImage->m_pPalette->m_type = RPal::P888;
- pImage->m_pPalette->m_sPalEntrySize = RPal::GetPalEntrySize(RPal::P888);
- IM_RGBQUAD* qpDib = (IM_RGBQUAD*) pDibPal->m_pData;
- IM_RGBTRIPLE* tp888 = (IM_RGBTRIPLE*) pImage->m_pPalette->m_pData;
- short i;
- // The DIB format when viewed as a IM_RGBQUAD = B|G|R|Reserved
- // Converting to 888 viewed as IM_RGBTRIPLE as B|G|R
- for (i = pDibPal->m_sStartIndex; i < pDibPal->m_sStartIndex + pDibPal->m_sNumEntries; i++)
- {
- tp888[i].rgbtBlue = qpDib[i].rgbBlue;
- tp888[i].rgbtGreen = qpDib[i].rgbGreen;
- tp888[i].rgbtRed = qpDib[i].rgbRed;
- }
- delete pDibPal;
- pImage->m_type = RImage::SCREEN8_888;
- sReturn = RImage::SCREEN8_888;
- break;
- }
- case RImage::SYSTEM8:
- case RImage::SCREEN8_555:
- case RImage::SCREEN8_565:
- {
- if (ConvertToBMP8(pImage) == RImage::BMP8)
- sReturn = ConvertToSCREEN8_888(pImage);
- else
- {
- TRACE("RImage::Convert - SCREEN8_888 Intermediate RImage::BMP8 translation error\n");
- sReturn = RImage::NOT_SUPPORTED;
- }
- break;
- }
- default:
- {
- sReturn = RImage::NOT_SUPPORTED;
- break;
- }
- }
- return sReturn;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // ConvertToSCREEN16_555
- //
- // Converts from RImage::BMP8 or BMP24 to SCREEN16_555. For RImage::BMP8 it creates
- // a 16-bit image buffer and then dereferences the color palette for
- // each pixel value in the 8-bit buffer. For BMP24 it creates a 16-bit
- // image buffer and converts the 24-bit buffer to a 16-bit image.
- //
- //////////////////////////////////////////////////////////////////////
- short ConvertToSCREEN16_555(RImage* pImage)
- {
- short sReturn = RImage::NOT_SUPPORTED;
- switch (pImage->m_type)
- {
- case RImage::SCREEN16_555:
- {
- sReturn = RImage::SCREEN16_555;
- break;
- }
- case RImage::BMP8:
- {
- long r, c, height, width, pitch;
- // Make sure that we copy the whole thing even if the
- // height and width are negative values
- height = labs((long)pImage->m_sHeight);
- width = labs((long)pImage->m_sWidth);
- pitch = pImage->m_lPitch;
- // Set up pointers to the 8-bit buffer before detaching
- UCHAR* ucp8 = pImage->m_pData;
- ULONG* ulpPal = (ULONG*) pImage->m_pPalette->m_pData;
- // Detach the 8-bit buffer from the Image
- void* pDetachedMemory = pImage->DetachData();
- // Create a new 16-bit buffer
- pImage->m_sDepth = 16;
- pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
- pImage->CreateData(pImage->m_lPitch * (short)pImage->m_sHeight);
- USHORT* usp16 = (USHORT*) pImage->m_pData;
- UCHAR ucIndex;
- long dPitch = pImage->m_lPitch / (pImage->m_sDepth / 8);
- for (r = 0; r < height; r++)
- for (c = 0; c < width; c++)
- {
- ucIndex = ucp8[r*pitch + c];
- usp16[r*dPitch + c] = (USHORT) (((ulpPal[ucIndex] & 0x00f80000) >> 9) + // Red
- ((ulpPal[ucIndex] & 0x0000f800) >> 6) + // Green
- ((ulpPal[ucIndex] & 0x000000f8) >> 3)); // Blue
- }
- RImage::DestroyDetachedData(&pDetachedMemory);
- pImage->DestroyPalette();
- pImage->m_type = RImage::SCREEN16_555;
- sReturn = RImage::SCREEN16_555;
- break;
- }
- case RImage::BMP24:
- {
- long r, c, height, width, sPitch;
- // Make sure that we copy the whole thing even if the
- // height and width are negative values
- height = labs((long)pImage->m_sHeight);
- width = labs((long)pImage->m_sWidth);
- sPitch = pImage->m_lPitch;
- // Set up a pointer to the 24-bit buffer before detaching
- UCHAR* ucp24 = (UCHAR*) pImage->m_pData;
- // Detach old 24-bit buffer from the Image
- void* pDetachedMem = pImage->DetachData();
- // Create a new 16-bit buffer and set a pointer to the data
- pImage->m_sDepth = 16;
- pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
- pImage->CreateData(pImage->m_lPitch * (long)pImage->m_sHeight);
- USHORT* usp16 = (USHORT*) pImage->m_pData;
- long dPitch = pImage->m_lPitch / (pImage->m_sDepth / 8);
- for (r = 0 ; r < height; r++)
- for (c = 0; c < width; c++)
- usp16[r*dPitch + c] = (USHORT) (
- ((((USHORT) ucp24[r*sPitch + 3*c+2]) & 0x00f8) << 7) + // Red
- ((((USHORT) ucp24[r*sPitch + 3*c+1]) & 0x00f8) << 2) + // Green
- ((((USHORT) ucp24[r*sPitch + 3*c+0]) & 0x00f8) >> 3)); // Blue
-
- RImage::DestroyDetachedData(&pDetachedMem);
- pImage->m_type = RImage::SCREEN16_555;
- sReturn = RImage::SCREEN16_555;
- break;
- }
- case RImage::SYSTEM8:
- case RImage::SCREEN8_555:
- case RImage::SCREEN8_565:
- case RImage::SCREEN8_888:
- {
- if (ConvertToBMP8(pImage) == RImage::BMP8)
- sReturn = ConvertToSCREEN16_555(pImage);
- else
- {
- TRACE("RImage::Convert - SCREEN16_555 Intermediate RImage::BMP8 translation error\n");
- sReturn = RImage::NOT_SUPPORTED;
- }
- break;
- }
- case RImage::SCREEN16_565:
- case RImage::SCREEN24_RGB:
- case RImage::SCREEN32_ARGB:
- {
- if (ConvertToBMP24(pImage) == RImage::BMP24)
- sReturn = ConvertToSCREEN16_555(pImage);
- else
- {
- TRACE("RImage::Convert - SCREEN16_555 Intermediate BMP24 translation error\n");
- sReturn = RImage::NOT_SUPPORTED;
- }
- break;
- }
- default:
- {
- sReturn = RImage::NOT_SUPPORTED;
- break;
- }
- }
- return sReturn;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // ConvertToSCREEN16_565
- //
- // Converts from RImage::BMP8 or BMP24 to SCREEN16_565. For RImage::BMP8 it creates
- // a 16-bit image buffer and then dereferences the color palette for
- // each pixel value in the 8-bit buffer. For BMP24 it creates a 16-bit
- // image buffer and converts the 24-bit buffer to a 16-bit image.
- //
- //////////////////////////////////////////////////////////////////////
- short ConvertToSCREEN16_565(RImage* pImage)
- {
- short sReturn = RImage::NOT_SUPPORTED;
- switch (pImage->m_type)
- {
- case RImage::SCREEN16_565:
- {
- sReturn = RImage::SCREEN16_565;
- break;
- }
- case RImage::BMP8:
- {
- long r, c, height, width, pitch;
- // Make sure that we copy the whole thing even if the
- // height and width are negative values
- height = labs((long)pImage->m_sHeight);
- width = labs((long)pImage->m_sWidth);
- pitch = pImage->m_lPitch;
- // Set up a pointer to the old 8-bit buffer before detaching
- UCHAR* ucp8 = pImage->m_pData;
- ULONG* ulpPal = (ULONG*) pImage->m_pPalette->m_pData;
- // Detach the 8-bit buffer from the Image
- void* pDetachedMem = pImage->DetachData();
- // Create a new 16-bit buffer and set pointers to the data
- pImage->m_sDepth = 16;
- pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
- pImage->CreateData(pImage->m_lPitch * (long)pImage->m_sHeight);
- USHORT* usp16 = (USHORT*) pImage->m_pData;
- UCHAR ucIndex;
- long dPitch = pImage->m_lPitch / (pImage->m_sDepth/8);
- for (r = 0; r < height; r++)
- for (c = 0; c < width; c++)
- {
- ucIndex = ucp8[r*pitch + c];
- usp16[r*dPitch + c] = (USHORT) (((ulpPal[ucIndex] & 0x00f80000) >> 8) + // Red
- ((ulpPal[ucIndex] & 0x0000fc00) >> 5) + // Green
- ((ulpPal[ucIndex] & 0x000000f8) >> 3)); // Blue
- }
- RImage::DestroyDetachedData(&pDetachedMem);
- pImage->DestroyPalette();
- pImage->m_type = RImage::SCREEN16_565;
- sReturn = RImage::SCREEN16_565;
- break;
- }
- case RImage::BMP24:
- {
- long r, c, height, width, sPitch;
- // Make sure that we copy the whole thing even if the
- // height and width are negative values
- height = labs((long)pImage->m_sHeight);
- width = labs((long)pImage->m_sWidth);
- sPitch = pImage->m_lPitch;
- // Set a pointer to the 24-bit buffer before detaching
- UCHAR* ucp24 = (UCHAR*) pImage->m_pData;
- // Detach the 24-bit buffer from the Image
- void* pDetachedMem = pImage->DetachData();
- // Create a new 16-bit buffer and set a pointer to the data
- pImage->m_sDepth = 16;
- pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
- pImage->CreateData(pImage->m_lPitch * (long)pImage->m_sHeight);
- USHORT* usp16 = (USHORT*) pImage->m_pData;
- long dPitch = pImage->m_lPitch / (pImage->m_sDepth / 8);
- for (r = 0 ; r < height; r++)
- for (c = 0; c < width; c++)
- usp16[r*dPitch + c] = (USHORT) (
- ((((USHORT) ucp24[r*sPitch + 3*c+2]) & 0x00f8) << 8) + // Red
- ((((USHORT) ucp24[r*sPitch + 3*c+1]) & 0x00fc) << 3) + // Green
- ((((USHORT) ucp24[r*sPitch + 3*c+0]) & 0x00f8) >> 3)); // Blue
-
- RImage::DestroyDetachedData(&pDetachedMem);
- pImage->m_type = RImage::SCREEN16_565;
- sReturn = RImage::SCREEN16_565;
- break;
- }
-
- case RImage::SYSTEM8:
- case RImage::SCREEN8_555:
- case RImage::SCREEN8_565:
- case RImage::SCREEN8_888:
- {
- if (ConvertToBMP8(pImage) == RImage::BMP8)
- sReturn = ConvertToSCREEN16_565(pImage);
- else
- {
- TRACE("RImage::Convert - SCREEN16_565 Intermediate RImage::BMP8 translation error\n");
- sReturn = RImage::NOT_SUPPORTED;
- }
- break;
- }
- case RImage::SCREEN16_555:
- case RImage::SCREEN24_RGB:
- case RImage::SCREEN32_ARGB:
- {
- if (ConvertToBMP24(pImage) == RImage::BMP24)
- sReturn = ConvertToSCREEN16_565(pImage);
- else
- {
- TRACE("RImage::Convert - SCREEN16_565 Intermediate BMP24 translation error\n");
- sReturn = RImage::NOT_SUPPORTED;
- }
- break;
- }
- default:
- {
- sReturn = RImage::NOT_SUPPORTED;
- break;
- }
- }
- return sReturn;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // ConvertToSCREEN24_RGB
- //
- // Converts from RImage::BMP8 or BMP24 to SCREEN32_RGB. For RImage::BMP8 it creates
- // a 24-bit buffer and then dereferences the color palette for each
- // pixel value in the 8-bit buffer. For BMP24 it is already in the
- // correct format and just changes the image type.
- //
- //////////////////////////////////////////////////////////////////////
- short ConvertToSCREEN24_RGB(RImage* pImage)
- {
- short sReturn = RImage::NOT_SUPPORTED;
- switch (pImage->m_type)
- {
- case RImage::SCREEN24_RGB:
- {
- sReturn = RImage::SCREEN24_RGB;
- break;
- }
- case RImage::BMP8:
- {
- long r, c, height, width, sPitch, dPitch;
- // Make sure that we copy the whole thing even if the
- // height and width are negative values
- height = labs((long)pImage->m_sHeight);
- width = labs((long)pImage->m_sWidth);
- sPitch = pImage->m_lPitch;
- // Set up a pointer to the 8-bit buffer before detaching
- UCHAR* ucp8 = pImage->m_pData;
- ULONG* ulPal = (ULONG*) pImage->m_pPalette->m_pData;
- // Detach the 8-bit buffer from the Image
- void* pDetachedMem = pImage->DetachData();
- // Create a new 24-bit buffer and set a pointer to the data
- pImage->m_sDepth = 24;
- dPitch = pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
- pImage->CreateData(pImage->m_lPitch * (long)pImage->m_sHeight);
- UCHAR* ucp24 = (UCHAR*) pImage->m_pData;
- ULONG ulColor;
- for (r = 0; r < height; r++)
- for (c = 0; c < width; c++)
- {
- ulColor = ulPal[ucp8[r*sPitch + c]];
- ucp24[r*dPitch + 3*c+0] = (UCHAR) (ulColor & 0x000000ff);
- ucp24[r*dPitch + 3*c+1] = (UCHAR) ((ulColor & 0x0000ff00) / 0x100);
- ucp24[r*dPitch + 3*c+2] = (UCHAR) ((ulColor & 0x00ff0000) / 0x10000);
- }
-
- RImage::DestroyDetachedData(&pDetachedMem);
- pImage->DestroyPalette();
- pImage->m_type = RImage::SCREEN24_RGB;
- sReturn = RImage::SCREEN24_RGB;
- break;
- }
- case RImage::BMP24:
- {
- pImage->m_type = RImage::SCREEN24_RGB;
- sReturn = RImage::SCREEN24_RGB;
- break;
- }
- case RImage::SYSTEM8:
- case RImage::SCREEN8_555:
- case RImage::SCREEN8_565:
- case RImage::SCREEN8_888:
- {
- if (ConvertToBMP8(pImage) == RImage::BMP8)
- sReturn = ConvertToSCREEN24_RGB(pImage);
- else
- {
- TRACE("RImage::Convert - SCREEN24_RGB Intermediate RImage::BMP8 translation error\n");
- sReturn = RImage::NOT_SUPPORTED;
- }
- break;
- }
- case RImage::SCREEN16_555:
- case RImage::SCREEN16_565:
- case RImage::SCREEN32_ARGB:
- {
- if (ConvertToBMP24(pImage) == RImage::BMP24)
- sReturn = ConvertToSCREEN24_RGB(pImage);
- else
- {
- TRACE("RImage::Convert - SCREEN24_RGB Intermediate BMP24 translation error\n");
- sReturn = RImage::NOT_SUPPORTED;
- }
- break;
- }
- default:
- {
- sReturn = RImage::NOT_SUPPORTED;
- break;
- }
- }
- return sReturn;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // ConvertToSCREEN32_ARGB
- //
- // Converts from RImage::BMP8 or BMP24 to SCREEN32_RGBA. For RImage::BMP8 it creates
- // a 32-bit buffer and then dereferences the color palette for each
- // pixel value in the 8-bit buffer. For BMP24 it creates a 32-bit
- // buffer and then translates the IM_RGBQUAD pixel values into RGBAlpha
- // "Screen Format" pixel values.
- //
- //////////////////////////////////////////////////////////////////////
- short ConvertToSCREEN32_ARGB(RImage* pImage)
- {
- short sReturn = RImage::NOT_SUPPORTED;
- switch (pImage->m_type)
- {
- case RImage::SCREEN32_ARGB:
- {
- sReturn = RImage::SCREEN32_ARGB;
- break;
- }
- case RImage::BMP8:
- {
- long r, c, height, width, pitch;
- // Make sure that we copy the whole thing even if the
- // height and width are negative values
- height = labs((long)pImage->m_sHeight);
- width = labs((long)pImage->m_sWidth);
- pitch = pImage->m_lPitch;
- // Set up a pointer to the 8-bit buffer before detaching
- UCHAR* ucp8 = pImage->m_pData;
- ULONG* ulPal = (ULONG*) pImage->m_pPalette->m_pData;
- // Detach the 8-bit buffer from the Image
- void* pDetachedMem = pImage->DetachData();
- // Create a new 32-bit buffer and set a pointer to the data
- pImage->m_sDepth = 32;
- pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
- pImage->CreateData(pImage->m_lPitch * (long)pImage->m_sHeight);
- ULONG* ulp32 = (ULONG*) pImage->m_pData;
- long dLongPitch = pImage->m_lPitch/4;
- for (r = 0; r < height; r++)
- for (c = 0; c < width; c++)
- ulp32[r*dLongPitch + c] = ulPal[ucp8[r*pitch + c]];
-
- RImage::DestroyDetachedData(&pDetachedMem);
- pImage->DestroyPalette();
- pImage->m_type = RImage::SCREEN32_ARGB;
- sReturn = RImage::SCREEN32_ARGB;
- break;
- }
- case RImage::BMP24:
- {
- long r, c, height, width, sPitch;
- // Make sure that we copy the whole thing even if the
- // height and width are negative values
- height = labs((long)pImage->m_sHeight);
- width = labs((long)pImage->m_sWidth);
- sPitch = pImage->m_lPitch;
- // Set a pointer to the 24-bit buffer before detaching
- UCHAR* ucp24 = (UCHAR*) pImage->m_pData;
- // Detach the 24-bit buffer from the Image
- void* pDetachedMem = pImage->DetachData();
- // Create a new 32-bit buffer and set a pointer to the data
- pImage->m_sDepth = 32;
- pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
- pImage->CreateData(pImage->m_lPitch * (long)pImage->m_sHeight);
- ULONG* ulp32 = (ULONG*) pImage->m_pData;
- long dLongPitch = pImage->m_lPitch/4;
- for (r = 0 ; r < height; r++)
- for (c = 0; c < width; c++)
- ulp32[r*dLongPitch + c] = (ULONG) (
- ((ULONG) ucp24[r*sPitch + 3*c+2] * 0x10000) +
- ((ULONG) ucp24[r*sPitch + 3*c+1] * 0x100) +
- ((ULONG) ucp24[r*sPitch + 3*c+0])) ;
-
- RImage::DestroyDetachedData(&pDetachedMem);
- pImage->m_type = RImage::SCREEN32_ARGB;
- sReturn = RImage::SCREEN32_ARGB;
- break;
- }
- case RImage::SYSTEM8:
- case RImage::SCREEN8_555:
- case RImage::SCREEN8_565:
- case RImage::SCREEN8_888:
- {
- if (ConvertToBMP8(pImage) == RImage::BMP8)
- sReturn = ConvertToSCREEN32_ARGB(pImage);
- else
- {
- TRACE("RImage::Convert - SCREEN32_ARGB Intermediate RImage::BMP8 translation error\n");
- sReturn = RImage::NOT_SUPPORTED;
- }
- break;
- }
- case RImage::SCREEN16_555:
- case RImage::SCREEN16_565:
- case RImage::SCREEN24_RGB:
- {
- if (ConvertToBMP24(pImage) == RImage::BMP24)
- sReturn = ConvertToSCREEN32_ARGB(pImage);
- else
- {
- TRACE("RImage::Convert - SCREEN32_ARGB Intermediate BMP24 translation error\n");
- sReturn = RImage::NOT_SUPPORTED;
- }
- break;
- }
- default:
- {
- sReturn = RImage::NOT_SUPPORTED;
- break;
- }
- }
- return sReturn;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Converts from the Window's compression format for 8 bit BMPs (RLE8)
- // RImage::BMP8RLE to RImage::BMP8 format. Palette is not touched.
- //
- // Description of this process from Win32 documentation:
- // This format can be compressed in encoded or absolute modes. Both
- // modes can occur anywhere in the same bitmap.
- // · Encoded mode consists of two bytes: the first byte specifies the
- // number of consecutive pixels to be drawn using the color index
- // contained in the second byte. In addition, the first byte of the pair
- // can be set to zero to indicate an escape that denotes an end of line,
- // end of bitmap, or delta. The interpretation of the escape depends on
- // the value of the second byte of the pair, which can be one of the
- // following:
- //
- // Value Meaning
- //
- // 0 End of line.
- // 1 End of bitmap.
- // 2 Delta. The two bytes following the escape contain unsigned values
- // indicating the horizontal and vertical offsets of the next pixel from
- // the current position.
- //
- // · In absolute mode, the first byte is zero and the second byte is a
- // value in the range 03H through FFH. The second byte represents the
- // number of bytes that follow, each of which contains the color index
- // of a single pixel. When the second byte is 2 or less, the escape has
- // the same meaning as in encoded mode. In absolute mode, each run must
- // be aligned on a word boundary.
- //
- //
- //////////////////////////////////////////////////////////////////////
- short ConvertFromBMP8RLE(RImage* pImage)
- {
- short sRes = RImage::NOT_SUPPORTED; // Assume failure.
- ASSERT(pImage->m_type == RImage::BMP8RLE);
- // Set up a pointer to the 8-bit compressed buffer before detaching
- U8* pu8Comp = pImage->m_pData;
- U8* pu8End = pu8Comp + pImage->m_ulSize;
- // Detach the 8-bit compressed buffer from the Image
- void* pvDetachedMem = pImage->DetachData();
- // Create a new 8-bit uncompressed buffer and set a pointer to the
- // data. Leave the current pitch.
- if (pImage->CreateData(pImage->m_lPitch * (long)pImage->m_sHeight) == 0)
- {
- U8* pu8Uncomp = pImage->m_pData;
- // We must flip the image during decompression.
- // This should work for both negative and positive
- // pitch buffers (i.e., upside down and right side up).
- long lPitch = -pImage->m_lPitch;
- pu8Uncomp = pu8Uncomp + pImage->m_lPitch * ((long)pImage->m_sHeight - 1);
- U8* pu8Row = pu8Uncomp;
- // Actual decompression. See function header for details.
- U8 u8Num; // Num pixels to run.
- U8 u8Pixel; // Pixel to run.
- short sDone = FALSE;
- while (sDone == FALSE && pu8Comp < pu8End)
- {
- // First byte is number of pixels to run, if not 0.
- u8Num = *pu8Comp++;
- if (u8Num > 0)
- {
- // Second byte is the pixel to run the u8Num pixels.
- u8Pixel = *pu8Comp++;
- // Intrinsic version of this should be faster than C.
- memset(pu8Uncomp, u8Pixel, u8Num);
- pu8Uncomp += u8Num;
- }
- else
- {
- // The number of bytes is 0, this is an "escape" or
- // absolute mode.
- // Second byte is the type of escape, unless 3 or more
- // which indicates the number of absolute bytes to copy.
- u8Num = *pu8Comp++;
- switch (u8Num)
- {
- case 0: // End of line.
- // Move to next line of destination.
- // We require these end of lines for correct decompression.
- pu8Row += lPitch;
- pu8Uncomp = pu8Row;
- break;
- case 1: // End of bitmap.
- sDone = TRUE;
- break;
- case 2:
- {
- // Move to position indicated by next two bytes relative
- // to this position. Horizontal first, vertical second.
- // This should only be used in the case of deltas and
- // I cannot see how that could ever be since this isn't
- // an animation format.
- U8 u8Horz = *pu8Comp++;
- U8 u8Vert = *pu8Comp++;
- pu8Uncomp += u8Horz + (u8Vert * lPitch);
- break;
- }
- default: // Absolute mode.
- // Intrinsic version of memcpy is fast; it aligns its copies
- // unless the compiler sucks.
- memcpy(pu8Uncomp, pu8Comp, u8Num);
- pu8Comp += u8Num;
- pu8Uncomp += u8Num;
- // This copy is supposed to be word aligned. It is not clearly
- // stated in the dox, but it seems that, if this was an odd
- // number of bytes, we should skip the next byte.
- if (u8Num % 2 != 0)
- {
- pu8Comp++;
- }
- break;
- }
- }
- }
- // Deallocate old buffer.
- RImage::DestroyDetachedData(&pvDetachedMem);
- pImage->m_type = RImage::BMP8;
- sRes = (short)pImage->m_type;
- }
- else
- {
- TRACE("ConvertFromBMP8RLE(): CreateData() failed.\n");
- // Re-attach old buffer.
- pImage->m_pMem = (UCHAR*)pvDetachedMem;
- }
- return sRes;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Converts to the Window's compression format for 8 bit BMPs (RLE8)
- // RImage::BMP8RLE from RImage::BMP8. Palette is not touched. See
- // description of this compression in comment header for
- // ConvertFromBMP8RLE.
- //
- //////////////////////////////////////////////////////////////////////
- short ConvertToBMP8RLE(RImage* pImage)
- {
- short sRes = RImage::NOT_SUPPORTED; // Assume failure.
- // Only certain types can be converted from.
- switch (pImage->m_type)
- {
- case RImage::BMP8:
- {
- // Set up a pointer to the 8-bit uncompressed buffer before detaching
- U8* pu8Uncomp = pImage->m_pData;
- // We must flip the image during compression.
- // This should work for both negative and positive
- // pitch buffers (i.e., upside down and right side up).
- long lPitch = -pImage->m_lPitch;
- pu8Uncomp = pu8Uncomp + pImage->m_lPitch * ((long)pImage->m_sHeight - 1);
- // Detach the 8-bit uncompressed buffer from the Image
- void* pvDetachedMem = pImage->DetachData();
- // Create a new 8-bit compressed buffer and set a pointer to the
- // data. Leave the current pitch. This buffer must be big enough for
- // the worst case compression (it could be infinitely large if I were
- // dumb and added many deltas that didn't do anything, but I won't
- // do that). I think the worst case for my algorithm is a run of 1 pixel
- // followed by a run of 1 different pixel, followed by a run of 1 or more
- // pixels different than the previous run. That's 6 bytes for 3 pixels?
- // plus end of lines, which 1 to 1 for the height. Therefore, I'm
- // assuming 2 times the pixels plus the height times 2 (2 bytes for each end
- // of line) plus 2 bytes for the end of bitmap is good enough.
- // 2 * ulSize + lHeight * 2 + 2.
- if (pImage->CreateData(2 * pImage->m_ulSize + (long)pImage->m_sHeight * 2 + 2) == 0)
- {
- U8* pu8Comp = pImage->m_pData;
- // Actual compression. See function header for details.
- U8* pu8Row = pu8Uncomp;
- long lRowRemain;
- long lRun;
- // Compress until we exceed buffer. Nothing has explicitly
- // said we should, but we will try to be row based. This works
- // well for flipping the image while we're compressing.
- // Note that we never use the escape for moving the current position.
- // It seems to me this would only be useful in animation.
- for (long lNumLines = (long)pImage->m_sHeight; lNumLines > 0; lNumLines--)
- {
- lRowRemain = (long)pImage->m_sWidth;
- while (lRowRemain > 0)
- {
- // Look for verbatim runs first since they are limited
- // to 3 or more.
- for (lRun = 1; lRun < lRowRemain && lRun < 255; lRun++)
- {
- if (pu8Uncomp[lRun] == pu8Uncomp[lRun - 1])
- {
- break;
- }
- }
- // If less than 3, do a one color run . . .
- if (lRun < 3)
- {
- // Look for length of run with one color index.
- for (lRun = 1; lRun < lRowRemain && lRun < 255; lRun++)
- {
- if (pu8Uncomp[lRun] != *pu8Uncomp)
- {
- break;
- }
- }
-
- // Number of pixels to run this color index.
- *pu8Comp++ = (U8)lRun;
- // Color index to run.
- *pu8Comp++ = *pu8Uncomp;
- // Advance past run.
- pu8Uncomp += lRun;
- }
- else
- {
- // 0 indicates "absolute mode".
- *pu8Comp++ = 0;
- // Number of absolute pixels.
- *pu8Comp++ = (U8)lRun;
- // Verbatim run.
- memcpy(pu8Comp, pu8Uncomp, lRun);
- // Advance uncomp.
- pu8Uncomp += lRun;
- // Advance comp.
- pu8Comp += lRun;
- // If this is an odd number . . .
- if ((lRun % 2) == 1)
- {
- // Skip to maintain "word align"ment. Make
- // ignored byte 0 for obviousness.
- *pu8Comp++ = 0;
- }
- }
-
- // Reduce amount left this row.
- lRowRemain -= lRun;
-
- ASSERT(lRowRemain >= 0);
- }
- // Add end of line escape.
- *pu8Comp++ = 0;
- *pu8Comp++ = 0;
- // Update row.
- pu8Row += lPitch;
- // Set ptr to new row.
- pu8Uncomp = pu8Row;
- }
- // Add end of BMP escape.
- *pu8Comp++ = 0;
- *pu8Comp++ = 1;
- // Get size of compressed buffer.
- ULONG ulSize = (pu8Comp - pImage->m_pData);
- // Deallocate old buffer.
- RImage::DestroyDetachedData(&pvDetachedMem);
- // Allocate again and copy.
- pu8Comp = pImage->m_pData;
- pvDetachedMem = pImage->DetachData();
- // Attempt to allocate new correctly sized buffer . . .
- if (pImage->CreateData(ulSize) == 0)
- {
- // Copy data.
- memcpy(pImage->m_pData, pu8Comp, pImage->m_ulSize);
- // Destroy old, too large compressed buffer.
- RImage::DestroyDetachedData(&pvDetachedMem);
- }
- else
- {
- TRACE("ConvertToBMP8RLE(): CreateData() failed for second compressed buffer.\n");
- // Re-attach old buffer.
- pImage->m_pMem = (UCHAR*)pvDetachedMem;
- }
- pImage->m_type = RImage::BMP8RLE;
- sRes = (short)pImage->m_type;
- }
- else
- {
- TRACE("ConvertToBMP8RLE(): CreateData() failed.\n");
- // Re-attach old buffer.
- pImage->m_pMem = (UCHAR*)pvDetachedMem;
- }
- break;
- }
-
- default:
- // Not supported.
- break;
- }
- return sRes;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Converts from RImage::BMP1 to RImage::BMP8. Palette is not touched, but
- // is NOT significant to BMP1 format (1 == Black, 0 == White).
- //
- //////////////////////////////////////////////////////////////////////
- short ConvertFromBMP1(RImage* pImage)
- {
- short sRes = RImage::NOT_SUPPORTED; // Assume failure.
- // Set up a pointer to the 1-bit packed buffer before detaching.
- U8* pu8Src = pImage->m_pData;
- // Detach the 1-bit packed buffer from the Image
- void* pvDetachedMem = pImage->DetachData();
- // Create a new 8-bit buffer and set a pointer to the
- // data. Alter the current pitch.
-
- // Set new depth.
- pImage->m_sDepth = 8;
- // Remember old pitch.
- long lSrcPitch = pImage->m_lPitch;
- // Compute the new pitch. Preserve sign.
- if (pImage->m_lPitch > 0)
- {
- pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
- }
- else
- {
- pImage->m_lPitch = -RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
- }
- // Allocate new data. This call sets ulSize. Preserve m_sWidth, m_sHeight.
- if (pImage->CreateData(pImage->m_sHeight * ABS(pImage->m_lPitch)) == 0)
- {
- // Destination.
- U8* pu8Dst = pImage->m_pData;
- // Row trackers.
- U8* pu8SrcRow = pu8Src;
- U8* pu8DstRow = pu8Dst;
- long lRows = (long)pImage->m_sHeight;
- long lCols;
- while (lRows-- > 0)
- {
- lCols = (long)pImage->m_sWidth / 8;
- while (lCols-- > 0)
- {
- // Pack a byte.
- *pu8Dst++ = *pu8Src >> 7;
- *pu8Dst++ = (*pu8Src & 0x40) >> 6;
- *pu8Dst++ = (*pu8Src & 0x20) >> 5;
- *pu8Dst++ = (*pu8Src & 0x10) >> 4;
- *pu8Dst++ = (*pu8Src & 0x08) >> 3;
- *pu8Dst++ = (*pu8Src & 0x04) >> 2;
- *pu8Dst++ = (*pu8Src & 0x02) >> 1;
- *pu8Dst++ = (*pu8Src++ & 0x01);
- }
- // Move "down" a row.
- pu8SrcRow += lSrcPitch;
- pu8DstRow += pImage->m_lPitch;
- // Update columns to beginning of row.
- pu8Src = pu8SrcRow;
- pu8Dst = pu8DstRow;
- }
- // Deallocate old buffer.
- RImage::DestroyDetachedData(&pvDetachedMem);
- // Set new type.
- pImage->m_type = RImage::BMP8;
- // Set return value.
- sRes = (short)pImage->m_type;
- }
- else
- {
- TRACE("ConvertToBMP1(): CreateData() failed.\n");
- // Re-attach old buffer.
- pImage->m_pMem = (UCHAR*)pvDetachedMem;
- }
- return sRes;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Converts to RImage::BMP1 from RImage::BMP8. Palette is not touched, but
- // is NOT significant to this format (1 == Black, 0 == White).
- //
- //////////////////////////////////////////////////////////////////////
- short ConvertToBMP1(RImage* pImage)
- {
- short sRes = RImage::NOT_SUPPORTED; // Assume failure.
- // Only certain types can be converted from.
- switch (pImage->m_type)
- {
- case RImage::BMP8:
- {
- // Set up a pointer to the 8-bit buffer before detaching.
- U8* pu8Src = pImage->m_pData;
- // Detach the 8-bit buffer from the Image
- void* pvDetachedMem = pImage->DetachData();
- // Create a new 1-bit packed buffer and set a pointer to the
- // data. Alter the current pitch.
-
- // Set new depth.
- pImage->m_sDepth = 1;
- // Remember old pitch.
- long lSrcPitch = pImage->m_lPitch;
- // If there is a partial byte . . .
- if ((pImage->m_lPitch % 8) != 0)
- {
- pImage->m_lPitch = (pImage->m_lPitch / 8);
-
- // Adjust appropriately for positive pitch . . .
- if (pImage->m_lPitch > 0)
- {
- pImage->m_lPitch++;
- }
- else // Negative pitch.
- {
- pImage->m_lPitch--;
- }
- }
- else
- {
- pImage->m_lPitch = (pImage->m_lPitch / 8);
- }
- // Allocate new data. This call sets ulSize. Preserve lWidth, lHeight.
- if (pImage->CreateData((long)pImage->m_sHeight * ABS(pImage->m_lPitch)) == 0)
- {
- // Bit packed destination.
- U8* pu8Dst = pImage->m_pData;
- // Row trackers.
- U8* pu8SrcRow = pu8Src;
- U8* pu8DstRow = pu8Dst;
- // Converts non-zero values to a 1 and increments ptr.
- #define CHECK_NONZERO_INC(p) ((*(p)++ == 0) ? 0 : 1)
- long lRows = (long)pImage->m_sHeight;
- long lCols;
- while (lRows-- > 0)
- {
- lCols = (long)pImage->m_sWidth / 8;
- while (lCols-- > 0)
- {
- // Pack a byte.
- *pu8Dst = CHECK_NONZERO_INC(pu8Src) << 7;
- *pu8Dst |= CHECK_NONZERO_INC(pu8Src) << 6;
- *pu8Dst |= CHECK_NONZERO_INC(pu8Src) << 5;
- *pu8Dst |= CHECK_NONZERO_INC(pu8Src) << 4;
- *pu8Dst |= CHECK_NONZERO_INC(pu8Src) << 3;
- *pu8Dst |= CHECK_NONZERO_INC(pu8Src) << 2;
- *pu8Dst |= CHECK_NONZERO_INC(pu8Src) << 1;
- *pu8Dst++ |= CHECK_NONZERO_INC(pu8Src) << 0;
- }
- // Move "down" a row.
- pu8SrcRow += lSrcPitch;
- pu8DstRow += pImage->m_lPitch;
- // Update columns to beginning of row.
- pu8Src = pu8SrcRow;
- pu8Dst = pu8DstRow;
- }
- // Deallocate old buffer.
- RImage::DestroyDetachedData(&pvDetachedMem);
- // Set new type.
- pImage->m_type = RImage::BMP1;
- // Set return value.
- sRes = (short)pImage->m_type;
- }
- else
- {
- TRACE("ConvertToBMP1(): CreateData() failed.\n");
- // Re-attach old buffer.
- pImage->m_pMem = (UCHAR*)pvDetachedMem;
- }
- break;
- }
-
- default:
- // Not supported.
- break;
- }
- return sRes;
- }
- //////////////////////////////////////////////////////////////////////
- // EOF
- //////////////////////////////////////////////////////////////////////
|