Imagecon.cpp 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 RWS Inc, All Rights Reserved
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of version 2 of the GNU General Public License as published by
  7. // the Free Software Foundation
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License along
  15. // with this program; if not, write to the Free Software Foundation, Inc.,
  16. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. //
  18. //////////////////////////////////////////////////////////////////////
  19. //
  20. // IMAGECON.CPP
  21. //
  22. // Created on 09/28/95 BRH
  23. // Implemented on 09/28/95 BRH
  24. //
  25. // 09/28/95 BRH Standard conversion functions for the standard
  26. // image types. The two main standards are 8 and 24
  27. // bit images. The standard converters are explained
  28. // below
  29. //
  30. // 11/03/95 BRH Added support for RPal's new sPalEntrySize. Any
  31. // conversion that changes the palette will also
  32. // update this variable.
  33. //
  34. // 11/06/95 BRH Fixed the ConvertToSCREEN8_888 to use the proper
  35. // 24-bit palette entries rather than the 32-bit
  36. // that it was using.
  37. //
  38. // 11/07/95 JMI Changed all occurrences of RGBQUAD to IM_RGBQUAD &
  39. // RGBTRIPLE to IM_RGBTRIPLE.
  40. //
  41. // 11/08/95 BRH Added several direct conversions to BMP8 and BMP24.
  42. // Previously we had BMP8 and BMP24 as our two base
  43. // types which then were converted to SCREEN8_xxx formats
  44. // and others. By providing a few more direct conversions
  45. // I can then provide almost any other conversion by
  46. // calling two conversion functions, one from the current
  47. // to BMP8 and then from BMP8 to the new format. The
  48. // only conversions not supported are high color or
  49. // true color images being converted to palette images.
  50. //
  51. // 11/15/95 BRH Change the conversion routines that deal with palettes
  52. // so that the images keep the original RPal object in
  53. // their pPalette pointers when the are converted.
  54. // Previously the conversion routines detached the
  55. // palette from the RImage and then created a new palette
  56. // and attached that to the RImage. This causes trouble
  57. // if there are other external pointers to the same RPal,
  58. // for example if several images use the same palette we
  59. // don't want to throw the palette out. Now the image
  60. // keeps the same RPal object and only the palette's data
  61. // is discarded during the conversion.
  62. //
  63. // 11/20/95 BRH Finished up all of the cross conversions between formats
  64. // using intermediate BMP8 or BMP24 translations when necessary.
  65. // Currently any standard format can be converted to any other
  66. // standard format with the exception that 32, 24, or 16 bit
  67. // images cannot be converted to any of the 8 bit formats due
  68. // to the lack of a good color reduction algorithm.
  69. //
  70. // 01/15/96 JMI Changed the array of conversion functions to a dynamic
  71. // linking mechanism of ConvertTo and ConvertFrom function
  72. // pointers so that new conversion functions can be added in
  73. // .cpp files other than imagecon.cpp.
  74. //
  75. // 01/16/96 BRH Added calls to RImage::GetPitch(width,depth) to calculate
  76. // the 128-bit aligned pitch for converted image types.
  77. // previously, several of the conversion functions forgot
  78. // to change the pitch for the new format.
  79. //
  80. // 01/19/96 BRH Fixed a bug in creating new buffers. Most calls were
  81. // incorrectly using width*height*(depth/8) where they should
  82. // have been using pitch instead of width.
  83. //
  84. // 02/27/95 BRH Changed over from using DYNALINK to the RImageSpecialFunc
  85. // class for Conversion functions. The new class is based on
  86. // the same concept as DYNALINK but is specialized for RImage
  87. // in that it supports 6 special function types for conversion
  88. // to/from, load/save, and alloc/delete. I moved the instantiation
  89. // of the static arrays from imagecon.cpp to image.cpp since
  90. // it now instantiates 6 arrays, 4 of which are not conversion
  91. // related. Then I changed the calls to LINKLATE macros (DYNALINK)
  92. // to IMAGELINKLATE macros (RImageSpecialFunc).
  93. //
  94. // 07/22/96 JMI Added ConvertFromBMP8RLE to allow LoadDib to load RLE8
  95. // compressed DIBs. BMP8RLE format can be used as any other
  96. // image format. Will implement ConvertToBMP8RLE soon.
  97. //
  98. // 07/23/96 JMI Added ConvertToBMP8RLE to allow one to convert into
  99. // BMP8RLE (RLE8 Windows' bitmap compressed format). The convert
  100. // flips upside down as it compresses making it official
  101. // as far as BMP files go. SaveDib is aware of this use of
  102. // RLE8 and can save these preserving compression.
  103. // Also, made ConvertFromBMP8RLE flip the image so you get
  104. // a DIB that is upside down as far as DIBs go, but right side
  105. // up to the naked eye. This is functionality was implemented
  106. // since LoadDib does this as well.
  107. //
  108. // 08/04/96 MJR Commented-out the "pImage" parameter to ConvertNoSupport()
  109. // to avoid compiler warning about "unused variable".
  110. // Also modified ConvertToSystem() to use WIN32 instead of
  111. // _WINDOWS and to use MAC instead of _MAC. However, note that
  112. // ConvertToSystem() still does nothing on the mac.
  113. //
  114. // 09/04/96 JMI Added BMP1 IMAGELINKLATE's and corresponding ConvertToBMP1()
  115. // and ConvertFromBMP1(). BMP8 is, as usual, the only type
  116. // convertible to BMP1.
  117. //
  118. // 10/10/96 JMI ConvertToBMP24() was not checking for error return from
  119. // CreateData() and so it was crashing when memory was
  120. // low.
  121. //
  122. // 10/30/96 JMI Changed:
  123. // Old label: New label:
  124. // ========= =========
  125. // RImage RImage
  126. // RPal RPal
  127. // ULONG ulType RImage::Type ulType
  128. //
  129. // Removed #include of "imagetyp.h" b/c it has been obsoleted.
  130. // Removed #include of "imagecon.h" b/c all it does is include
  131. // image.h and then redeclare RImage (now RImage anyway) and
  132. // replaced with #include of image.h.
  133. //
  134. // 11/01/96 JMI Changed all members of image to be preceded by m_ (e.g.,
  135. // sDepth to m_sDepth). Changed all position members (i.e.,
  136. // lWidth, lHeight, lBufferWidth, lBufferHeight, lXPos, & lYPos)
  137. // to be shorts (i.e., m_sWidth, m_sHeight, m_sBufferWidth,
  138. // m_sBufferHeight, m_sXPos, m_sYPos). Changed ulType to
  139. // m_type and ulDestinationType to m_typeDestination.
  140. //
  141. // 11/06/96 MJR Added "RImage::: before many instances of BMP8, BMP24, etc.
  142. // This was suddenly required because the IMAGELINKLATE macro
  143. // no longer used the "using" syntax which had, as a side-effect,
  144. // allowed the use of the enums without a preceeding "RImage::".
  145. //
  146. // 11/08/96 JMI Added more "RImage::"s where necessary in the #ifdef WIN32
  147. // block.
  148. //
  149. // 11/08/96 JMI Changed reference of BMP8RLE to RImage::BMP8RLE in an ASSERT.
  150. //
  151. // Standard Converters:
  152. //
  153. // Buffer Conversions:
  154. //
  155. // BMP8 (8-bit buffer 32-bit color pal) -> 16-bit buffer (555)
  156. // BMP8 (8-bit buffer 32-bit color pal) -> 16-bit buffer (565)
  157. // BMP8 (8-bit buffer 32-bit color pal) -> 24-bit buffer (888) RGB
  158. // BMP8 (8-bit buffer 32-bit color pal) -> 32-bit buffer (8888) ARGB
  159. // BMP24 (24-bit buffer) -> 16-bit buffer (555)
  160. // BMP24 (24-bit buffer) -> 16-bit buffer (565)
  161. // BMP24 (24-bit buffer) -> 32-bit buffer (8888) ARGB
  162. //
  163. // Palette Conversions:
  164. //
  165. // BMP8 (IM_RGBQUAD) -> 555 Palette
  166. // BMP8 (IM_RGBQUAD) -> 565 Palette
  167. // BMP8 (IM_RGBQUAD) -> 888 Palette
  168. // BMP8 (IM_RGBQUAD) -> SYSTEM Palette (for setting colors on a platform
  169. // basis) Windows = IM_RGBQUAD, Mac = Mac System Pal
  170. //
  171. //
  172. //////////////////////////////////////////////////////////////////////
  173. #include <stdlib.h>
  174. #include <string.h>
  175. #include "Image.h"
  176. //////////////////////////////////////////////////////////////////////
  177. // Prototypes.
  178. //////////////////////////////////////////////////////////////////////
  179. short ConvertNoSupport(RImage* pImage);
  180. short ConvertToBMP8(RImage* pImage);
  181. short ConvertToBMP24(RImage* pImage);
  182. short ConvertToSystem(RImage* pImage);
  183. short ConvertToSCREEN8_555(RImage* pImage);
  184. short ConvertToSCREEN8_565(RImage* pImage);
  185. short ConvertToSCREEN8_888(RImage* pImage);
  186. short ConvertToSCREEN16_555(RImage* pImage);
  187. short ConvertToSCREEN16_565(RImage* pImage);
  188. short ConvertToSCREEN24_RGB(RImage* pImage);
  189. short ConvertToSCREEN32_ARGB(RImage* pImage);
  190. IMAGELINKLATE(BMP8, ConvertToBMP8, NULL, NULL, NULL, NULL, NULL);
  191. IMAGELINKLATE(SYSTEM8, ConvertToSystem, NULL, NULL, NULL, NULL, NULL);
  192. IMAGELINKLATE(SCREEN8_555, ConvertToSCREEN8_555, NULL, NULL, NULL, NULL, NULL);
  193. IMAGELINKLATE(SCREEN8_565, ConvertToSCREEN8_565, NULL, NULL, NULL, NULL, NULL);
  194. IMAGELINKLATE(SCREEN8_888, ConvertToSCREEN8_888, NULL, NULL, NULL, NULL, NULL);
  195. IMAGELINKLATE(BMP24, ConvertToBMP24, NULL, NULL, NULL, NULL, NULL);
  196. IMAGELINKLATE(SCREEN16_555, ConvertToSCREEN16_555, NULL, NULL, NULL, NULL, NULL);
  197. IMAGELINKLATE(SCREEN16_565, ConvertToSCREEN16_565, NULL, NULL, NULL, NULL, NULL);
  198. IMAGELINKLATE(SCREEN24_RGB, ConvertToSCREEN24_RGB, NULL, NULL, NULL, NULL, NULL);
  199. IMAGELINKLATE(SCREEN32_ARGB, ConvertToSCREEN32_ARGB, NULL, NULL, NULL, NULL, NULL);
  200. //////////////////////////////////////////////////////////////////////
  201. // More non-standard, always supported types:
  202. //////////////////////////////////////////////////////////////////////
  203. // BMP compression format (BMP8RLE).
  204. short ConvertToBMP8RLE(RImage* pImage);
  205. short ConvertFromBMP8RLE(RImage* pImage);
  206. // Link in conversion functions.
  207. IMAGELINKLATE(BMP8RLE, ConvertToBMP8RLE, ConvertFromBMP8RLE, NULL, NULL, NULL, NULL);
  208. // Monochrome BMP (BMP1).
  209. short ConvertToBMP1(RImage* pImage);
  210. short ConvertFromBMP1(RImage* pImage);
  211. // Link in conversion functions.
  212. IMAGELINKLATE(BMP1, ConvertToBMP1, ConvertFromBMP1, NULL, NULL, NULL, NULL);
  213. //////////////////////////////////////////////////////////////////////
  214. //
  215. // ConvertNoSupport:
  216. //
  217. // Catch function in case somebody passes in a format that is not
  218. // supported. This function will just return RImage::NOT_SUPPORTED
  219. //
  220. //////////////////////////////////////////////////////////////////////
  221. short ConvertNoSupport(RImage* /*pImage*/)
  222. {
  223. TRACE("RImage::Convert - Conversion not supported - Invalid image type\n");
  224. return RImage::NOT_SUPPORTED;
  225. }
  226. //////////////////////////////////////////////////////////////////////
  227. //
  228. // ConvertToBMP8
  229. //
  230. // For now this conversion is not supported. RImage::BMP8 is a standard
  231. // load format so it is not apparent at this time why one couldn't
  232. // simply use the load function to obtain a RImage::BMP8 format. We don't
  233. // see the need to convert from one of the other formats into RImage::BMP8
  234. // but if it becomes necessary or convenient then it can be supported
  235. //
  236. //////////////////////////////////////////////////////////////////////
  237. short ConvertToBMP8(RImage* pImage)
  238. {
  239. short sReturn;
  240. switch (pImage->m_type)
  241. {
  242. case RImage::BMP8:
  243. {
  244. sReturn = RImage::BMP8;
  245. break;
  246. }
  247. case RImage::SYSTEM8:
  248. {
  249. #ifdef _WINDOWS
  250. pImage->m_type = RImage::BMP8;
  251. pImage->m_pPalette->m_type = RPal::PDIB;
  252. return RImage::BMP8;
  253. #endif
  254. break;
  255. }
  256. case RImage::SCREEN8_555:
  257. {
  258. // Make a copy of the original palette
  259. RPal* p555Pal = new RPal();
  260. *p555Pal = *pImage->m_pPalette;
  261. // Detach the original palette data from the Image's palette
  262. p555Pal->m_pData = pImage->m_pPalette->DetachData();
  263. // Create new palette data for the pImage
  264. pImage->m_pPalette->CreateData((p555Pal->m_sStartIndex + p555Pal->m_sNumEntries) * RPal::GetPalEntrySize(RPal::PDIB));
  265. pImage->m_pPalette->m_type = RPal::PDIB;
  266. pImage->m_pPalette->m_sPalEntrySize = RPal::GetPalEntrySize(RPal::PDIB);
  267. USHORT* usp555 = (USHORT*) p555Pal->m_pData;
  268. ULONG* ulpDib = (ULONG*) pImage->m_pPalette->m_pData;
  269. short i;
  270. // The 555 viewed as USHORT as xR5|G5|B5
  271. // viewed as 2 BYTES G3|B5|x|R5|G2
  272. // The DIB viewed as ULONG is Reserved|R|G|B
  273. // viewed as 4 BYTES B|G|R|Reserved
  274. for (i = p555Pal->m_sStartIndex; i < p555Pal->m_sStartIndex + p555Pal->m_sNumEntries; i++)
  275. ulpDib[i] = (ULONG) (((usp555[i] & 0x7c00) << 9) + // Red
  276. ((usp555[i] & 0x03e0) << 6) + // Green
  277. ((usp555[i] & 0x001f) << 3)); // Blue
  278. delete p555Pal;
  279. pImage->m_type = RImage::BMP8;
  280. sReturn = RImage::BMP8;
  281. break;
  282. }
  283. case RImage::SCREEN8_565:
  284. {
  285. // Make a copy of the original palette
  286. RPal* p565Pal = new RPal();
  287. *p565Pal = *pImage->m_pPalette;
  288. // Detach the original palette data from the Image's palette
  289. p565Pal->m_pData = pImage->m_pPalette->DetachData();
  290. // Create new palette data for the pImage
  291. pImage->m_pPalette->CreateData((p565Pal->m_sStartIndex + p565Pal->m_sNumEntries) * RPal::GetPalEntrySize(RPal::PDIB));
  292. pImage->m_pPalette->m_type = RPal::PDIB;
  293. pImage->m_pPalette->m_sPalEntrySize = RPal::GetPalEntrySize(RPal::PDIB);
  294. USHORT* usp565 = (USHORT*) p565Pal->m_pData;
  295. ULONG* ulpDib = (ULONG*) pImage->m_pPalette->m_pData;
  296. short i;
  297. // The 565 when viewed as USHORT R5|G6|B5
  298. // viewed as 2 BYTES G3|B5|R5|G3
  299. // The DIB when viewed as ULONG Reserved|R|G|B
  300. // viewed as 4 BYTES B|G|R|Reserved
  301. for (i = p565Pal->m_sStartIndex; i < p565Pal->m_sStartIndex + p565Pal->m_sNumEntries; i++)
  302. ulpDib[i] = (ULONG) (((usp565[i] & 0xf800) << 8) + // Red
  303. ((usp565[i] & 0x07e0) << 5) + // Green
  304. ((usp565[i] & 0x001f) << 3)); // Blue
  305. delete p565Pal;
  306. pImage->m_type = RImage::BMP8;
  307. sReturn = RImage::BMP8;
  308. break;
  309. }
  310. case RImage::SCREEN8_888:
  311. {
  312. // Make a copy of the original palette
  313. RPal* p888Pal = new RPal();
  314. *p888Pal = *pImage->m_pPalette;
  315. // Detach the original palette data form the Image's palette
  316. p888Pal->m_pData = pImage->m_pPalette->DetachData();
  317. // Create new palette data for the pImage
  318. pImage->m_pPalette->CreateData((p888Pal->m_sStartIndex + p888Pal->m_sNumEntries) * sizeof(IM_RGBQUAD));
  319. pImage->m_pPalette->m_type = RPal::PDIB;
  320. pImage->m_pPalette->m_sPalEntrySize = RPal::GetPalEntrySize(RPal::PDIB);
  321. IM_RGBTRIPLE* tp888 = (IM_RGBTRIPLE*) p888Pal->m_pData;
  322. IM_RGBQUAD* qpDib = (IM_RGBQUAD*) pImage->m_pPalette->m_pData;
  323. short i;
  324. // The DIB format when viewed as a IM_RGBQUAD = B|G|R|Reserved
  325. // The 888 palette viewed as IM_RGBTRIPLE B|G|R
  326. for (i = p888Pal->m_sStartIndex; i < p888Pal->m_sStartIndex + p888Pal->m_sNumEntries; i++)
  327. {
  328. qpDib[i].rgbBlue = tp888[i].rgbtBlue;
  329. qpDib[i].rgbGreen = tp888[i].rgbtGreen;
  330. qpDib[i].rgbRed = tp888[i].rgbtRed;
  331. qpDib[i].rgbReserved = 0;
  332. }
  333. delete p888Pal;
  334. pImage->m_type = RImage::BMP8;
  335. sReturn = RImage::BMP8;
  336. break;
  337. }
  338. default:
  339. {
  340. sReturn = RImage::NOT_SUPPORTED;
  341. break;
  342. }
  343. }
  344. return sReturn;
  345. }
  346. //////////////////////////////////////////////////////////////////////
  347. //
  348. // ConvertToBMP24
  349. //
  350. // For now this conversion is not supported. BMP24 is a standard
  351. // load format which would normally either be used as BMP24 after
  352. // the load or converted to one of the other image formats.
  353. //
  354. //////////////////////////////////////////////////////////////////////
  355. short ConvertToBMP24(RImage* pImage)
  356. {
  357. short sReturn;
  358. switch (pImage->m_type)
  359. {
  360. case RImage::BMP24:
  361. {
  362. sReturn = RImage::BMP24;
  363. break;
  364. }
  365. case RImage::BMP8:
  366. {
  367. ConvertToSCREEN24_RGB(pImage);
  368. pImage->m_type = RImage::BMP24;
  369. sReturn = RImage::BMP24;
  370. break;
  371. }
  372. case RImage::SCREEN8_555:
  373. case RImage::SCREEN8_565:
  374. case RImage::SCREEN8_888:
  375. case RImage::SYSTEM8:
  376. {
  377. if (ConvertToBMP8(pImage) == RImage::BMP8)
  378. sReturn = ConvertToBMP24(pImage);
  379. else
  380. {
  381. TRACE("RImage::Convert - BMP24: Intermediate RImage::BMP8 translation error\n");
  382. sReturn = RImage::NOT_SUPPORTED;
  383. }
  384. break;
  385. }
  386. case RImage::SCREEN24_RGB:
  387. {
  388. pImage->m_type = RImage::BMP24;
  389. sReturn = RImage::BMP24;
  390. break;
  391. }
  392. case RImage::SCREEN32_ARGB:
  393. {
  394. long r, c, height, width, sPitch;
  395. // Make sure that we copy the whole thing even if the
  396. // height and width are negative values
  397. height = labs((long)pImage->m_sHeight);
  398. width = labs((long)pImage->m_sWidth);
  399. sPitch = pImage->m_lPitch;
  400. // Set a pointer to the 32-bit buffer before detaching
  401. ULONG* ulp32 = (ULONG*) pImage->m_pData;
  402. // Detach the 32-bit buffer from the Image
  403. void* pDetachedMem = pImage->DetachData();
  404. // Create a new 24-bit buffer and set a pointer to the data
  405. pImage->m_sDepth = 24;
  406. pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
  407. if (pImage->CreateData(pImage->m_lPitch * (long)pImage->m_sHeight) == 0)
  408. {
  409. UCHAR* ucp24 = (UCHAR*) pImage->m_pData;
  410. long sPitchWidth = sPitch / 4;
  411. for (r = 0; r < height; r++)
  412. for (c = 0; c < width; c++)
  413. {
  414. ULONG ulPixel = ulp32[r*sPitchWidth + c];
  415. ucp24[r*pImage->m_lPitch + 3*c+0] = (UCHAR) (ulPixel & 0x000000ff); // Red
  416. ucp24[r*pImage->m_lPitch + 3*c+1] = (UCHAR) ((ulPixel & 0x0000ff00) >> 8); // Green
  417. ucp24[r*pImage->m_lPitch + 3*c+2] = (UCHAR) ((ulPixel & 0x00ff0000) >> 16);// Blue
  418. }
  419. RImage::DestroyDetachedData(&pDetachedMem);
  420. pImage->m_type = RImage::BMP24;
  421. sReturn = RImage::BMP24;
  422. }
  423. else
  424. {
  425. // Restore memory.
  426. pImage->m_pMem = (UCHAR*)pDetachedMem;
  427. pImage->m_pData = (UCHAR*)ulp32;
  428. TRACE("ConvertToBMP24(): CreateData() failed.\n");
  429. // Return old type.
  430. sReturn = (short)pImage->m_type;
  431. }
  432. break;
  433. }
  434. case RImage::SCREEN16_555:
  435. {
  436. long r, c, height, width, sPitch;
  437. // Make sure that we copy the whole thing even if the
  438. // height and width are negative values
  439. height = labs((long)pImage->m_sHeight);
  440. width = labs((long)pImage->m_sWidth);
  441. sPitch = pImage->m_lPitch;
  442. // Set up a pointer to the 16-bit buffer before detaching
  443. USHORT* usp16 = (USHORT*) pImage->m_pData;
  444. // Detach old 16-bit buffer from the Image
  445. void* pDetachedMem = pImage->DetachData();
  446. // Create a new 24-bit buffer and set a pointer to the data
  447. pImage->m_sDepth = 24;
  448. pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
  449. pImage->CreateData(pImage->m_lPitch * (long)pImage->m_sHeight);
  450. UCHAR* ucp24 = (UCHAR*) pImage->m_pData;
  451. long sPitchWidth = sPitch/2;
  452. for (r = 0; r < height; r++)
  453. for (c = 0; c < width; c++)
  454. {
  455. USHORT usPixel = usp16[r*sPitchWidth + c];
  456. ucp24[r*pImage->m_lPitch + 3*c+2] = (UCHAR) ((usPixel & 0x7c00) >> 7); // Red
  457. ucp24[r*pImage->m_lPitch + 3*c+1] = (UCHAR) ((usPixel & 0x03e0) >> 2); // Green
  458. ucp24[r*pImage->m_lPitch + 3*c+0] = (UCHAR) ((usPixel & 0x001f) << 3); // Blue
  459. }
  460. RImage::DestroyDetachedData(&pDetachedMem);
  461. pImage->m_type = RImage::BMP24;
  462. sReturn = RImage::BMP24;
  463. break;
  464. }
  465. case RImage::SCREEN16_565:
  466. {
  467. long r, c, height, width, sPitch;
  468. // Make sure that we copy the whole thing even if the
  469. // height and width are negative values
  470. height = labs((long)pImage->m_sHeight);
  471. width = labs((long)pImage->m_sWidth);
  472. sPitch = pImage->m_lPitch;
  473. // Set a pointer to the 16-bit buffer before detaching
  474. USHORT* usp16 = (USHORT*) pImage->m_pData;
  475. // Detach the 16-bit buffer from the Image
  476. void* pDetachedMem = pImage->DetachData();
  477. // Create a new 24-bit buffer and set a pointer to the data
  478. pImage->m_sDepth = 24;
  479. pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
  480. pImage->CreateData(pImage->m_lPitch * (long)pImage->m_sHeight);
  481. UCHAR* ucp24 = (UCHAR*) pImage->m_pData;
  482. long sPitchWidth = sPitch/2;
  483. for (r = 0; r < height; r++)
  484. for (c = 0; c < width; c++)
  485. {
  486. USHORT usPixel = usp16[r*sPitchWidth + c];
  487. ucp24[r*pImage->m_lPitch + 3*c+2] = (UCHAR) ((usPixel & 0xf800) >> 8); // Red
  488. ucp24[r*pImage->m_lPitch + 3*c+1] = (UCHAR) ((usPixel & 0x07e0) >> 3); // Green
  489. ucp24[r*pImage->m_lPitch + 3*c+0] = (UCHAR) ((usPixel & 0x001f) << 3); // Blue
  490. }
  491. RImage::DestroyDetachedData(&pDetachedMem);
  492. pImage->m_type = RImage::BMP24;
  493. sReturn = RImage::BMP24;
  494. break;
  495. }
  496. default:
  497. {
  498. sReturn = RImage::NOT_SUPPORTED;
  499. break;
  500. }
  501. }
  502. return sReturn;
  503. }
  504. //////////////////////////////////////////////////////////////////////
  505. //
  506. // ConvertToSystem
  507. //
  508. // This convert function will depened on what platform it is complied
  509. // on. Our standard load formats are Windows BMP. This function for
  510. // Windows will only change the type from RImage::BMP8 to RImage::SYSTEM8. On a Mac
  511. // it would convert the palette from IM_RGBQUAD to the Mac's system
  512. // palette.
  513. //
  514. //////////////////////////////////////////////////////////////////////
  515. short ConvertToSystem(RImage* pImage)
  516. {
  517. short sReturn = RImage::NOT_SUPPORTED;
  518. #ifdef WIN32
  519. switch (pImage->m_type)
  520. {
  521. case RImage::SYSTEM8:
  522. {
  523. sReturn = RImage::SYSTEM8;
  524. break;
  525. }
  526. case RImage::BMP8:
  527. {
  528. pImage->m_type = RImage::SYSTEM8;
  529. pImage->m_pPalette->m_type = RPal::PSYS;
  530. sReturn = RImage::SYSTEM8;
  531. break;
  532. }
  533. case RImage::SCREEN8_555:
  534. case RImage::SCREEN8_565:
  535. case RImage::SCREEN8_888:
  536. {
  537. if (ConvertToBMP8(pImage) == RImage::BMP8)
  538. sReturn = ConvertToSystem(pImage);
  539. else
  540. {
  541. TRACE("RImage::Convert - RImage::SYSTEM8: Intermediate RImage::BMP8 translation error\n");
  542. sReturn = RImage::NOT_SUPPORTED;
  543. }
  544. break;
  545. }
  546. default:
  547. {
  548. sReturn = RImage::NOT_SUPPORTED;
  549. break;
  550. }
  551. }
  552. #endif
  553. return sReturn;
  554. }
  555. //////////////////////////////////////////////////////////////////////
  556. //
  557. // ConvertToSCREEN8_555
  558. //
  559. // Converts from RImage::BMP8 to SCREEN8_555 which means that it transforms
  560. // the palette entries from IM_RGBQUAD to the 555 "Screen Format" palette
  561. //
  562. //////////////////////////////////////////////////////////////////////
  563. short ConvertToSCREEN8_555(RImage* pImage)
  564. {
  565. short sReturn;
  566. switch (pImage->m_type)
  567. {
  568. case RImage::SCREEN8_555:
  569. {
  570. sReturn = RImage::SCREEN8_555;
  571. break;
  572. }
  573. case RImage::BMP8:
  574. {
  575. // Make a copy of the original palette
  576. RPal* pDibPal = new RPal();
  577. *pDibPal = *pImage->m_pPalette;
  578. // Detach the original palette data from the Image's palette
  579. pDibPal->m_pData = pImage->m_pPalette->DetachData();
  580. // Create new palette data for the Image
  581. pImage->m_pPalette->CreateData((pDibPal->m_sStartIndex + pDibPal->m_sNumEntries) * 2);
  582. pImage->m_pPalette->m_type = RPal::P555;
  583. pImage->m_pPalette->m_sPalEntrySize = RPal::GetPalEntrySize(RPal::P555);
  584. ULONG* ulpDib = (ULONG*) pDibPal->m_pData;
  585. USHORT* usp555 = (USHORT*) pImage->m_pPalette->m_pData;
  586. short i;
  587. // The DIB format when viewed as a ULONG is Reserved|R|G|B
  588. // when viewed as 4 BYTES is B|G|R|Reserved
  589. // Converting to 555 viewed as USHORT as xR5|G5|B5
  590. // viewed as 2 BYTES G3|B5|x|R5|G2
  591. for (i = pDibPal->m_sStartIndex; i < pDibPal->m_sStartIndex + pDibPal->m_sNumEntries; i++)
  592. usp555[i] = (USHORT) (((ulpDib[i] & 0x00f80000) >> 9) + // Red
  593. ((ulpDib[i] & 0x0000f800) >> 6) + // Green
  594. ((ulpDib[i] & 0x000000f8) >> 3)); // Blue
  595. delete pDibPal;
  596. pImage->m_type = RImage::SCREEN8_555;
  597. sReturn = RImage::SCREEN8_555;
  598. break;
  599. }
  600. case RImage::SYSTEM8:
  601. case RImage::SCREEN8_565:
  602. case RImage::SCREEN8_888:
  603. {
  604. if (ConvertToBMP8(pImage) == RImage::BMP8)
  605. sReturn = ConvertToSCREEN8_555(pImage);
  606. else
  607. {
  608. TRACE("RImage::Convert - SCREEN8_555 Intermediate RImage::BMP8 translation error\n");
  609. sReturn = RImage::NOT_SUPPORTED;
  610. }
  611. }
  612. default:
  613. {
  614. sReturn = RImage::NOT_SUPPORTED;
  615. break;
  616. }
  617. }
  618. return sReturn;
  619. }
  620. //////////////////////////////////////////////////////////////////////
  621. //
  622. // ConvertToSCREEN8_565
  623. //
  624. // Converts from RImage::BMP8 to SCREEN8_565 which means that it transforms
  625. // the palette entries from IM_RGBQUAD to the 565 "Screen Format" palette
  626. //
  627. //////////////////////////////////////////////////////////////////////
  628. short ConvertToSCREEN8_565(RImage* pImage)
  629. {
  630. short sReturn;
  631. switch (pImage->m_type)
  632. {
  633. case RImage::SCREEN8_565:
  634. {
  635. sReturn = RImage::SCREEN8_565;
  636. break;
  637. }
  638. case RImage::BMP8:
  639. {
  640. // Make a copy of the original palette
  641. RPal* pDibPal = new RPal();
  642. *pDibPal = *pImage->m_pPalette;
  643. // Detach the original palette data from the Image's palette
  644. pDibPal->m_pData = pImage->m_pPalette->DetachData();
  645. // Create new palette data for the pImage
  646. pImage->m_pPalette->CreateData((pDibPal->m_sStartIndex + pDibPal->m_sNumEntries) * 2);
  647. pImage->m_pPalette->m_type = RPal::P565;
  648. pImage->m_pPalette->m_sPalEntrySize = RPal::GetPalEntrySize(RPal::P565);
  649. ULONG* ulpDib = (ULONG*) pDibPal->m_pData;
  650. USHORT* usp565 = (USHORT*) pImage->m_pPalette->m_pData;
  651. short i;
  652. // The DIB format when viewed as a ULONG is Reserved|R|G|B
  653. // when viewed as 4 BYTES is B|G|R|Reserved
  654. // Converting to 565 viewed as USHORT as R5|G6|B5
  655. // viewed as 2 BYTES G3|B5|R5|G3
  656. for (i = pDibPal->m_sStartIndex; i < pDibPal->m_sStartIndex + pDibPal->m_sNumEntries; i++)
  657. usp565[i] = (USHORT) (((ulpDib[i] & 0x00f80000) >> 8) + // Red
  658. ((ulpDib[i] & 0x0000fc00) >> 5) + // Green
  659. ((ulpDib[i] & 0x000000f8) >> 3)); // Blue
  660. delete pDibPal;
  661. pImage->m_type = RImage::SCREEN8_565;
  662. sReturn = RImage::SCREEN8_565;
  663. break;
  664. }
  665. case RImage::SYSTEM8:
  666. case RImage::SCREEN8_555:
  667. case RImage::SCREEN8_888:
  668. {
  669. if (ConvertToBMP8(pImage) == RImage::BMP8)
  670. sReturn = ConvertToSCREEN8_565(pImage);
  671. else
  672. {
  673. TRACE("RImage::Convert - SCREEN8_565 Intermediate RImage::BMP8 translation error\n");
  674. sReturn = RImage::NOT_SUPPORTED;
  675. }
  676. break;
  677. }
  678. default:
  679. {
  680. sReturn = RImage::NOT_SUPPORTED;
  681. break;
  682. }
  683. }
  684. return sReturn;
  685. }
  686. //////////////////////////////////////////////////////////////////////
  687. //
  688. // ConvertToSCREEN8_888
  689. //
  690. // Converts from RImage::BMP8 to SCREEN8_888 which means that it transforms
  691. // the palette entries from IM_RGBQUAD to the 888 "Screen Format" palette
  692. //
  693. // The normal RImage::BMP8 DIB palette
  694. // when viewed as ULONG is Reserved|R|G|B
  695. //
  696. // And the screen format is the same, so just change the image type
  697. //
  698. //////////////////////////////////////////////////////////////////////
  699. short ConvertToSCREEN8_888(RImage* pImage)
  700. {
  701. short sReturn;
  702. switch(pImage->m_type)
  703. {
  704. case RImage::SCREEN8_888:
  705. {
  706. sReturn = RImage::SCREEN8_888;
  707. break;
  708. }
  709. case RImage::BMP8:
  710. {
  711. RPal* pDibPal = new RPal();
  712. *pDibPal = *pImage->m_pPalette;
  713. // Detach the original palette data from the Image's palette
  714. pDibPal->m_pData = pImage->m_pPalette->DetachData();
  715. // Create new palette data for the pImage
  716. pImage->m_pPalette->CreateData((pDibPal->m_sStartIndex + pDibPal->m_sNumEntries) * sizeof(IM_RGBTRIPLE));
  717. pImage->m_pPalette->m_type = RPal::P888;
  718. pImage->m_pPalette->m_sPalEntrySize = RPal::GetPalEntrySize(RPal::P888);
  719. IM_RGBQUAD* qpDib = (IM_RGBQUAD*) pDibPal->m_pData;
  720. IM_RGBTRIPLE* tp888 = (IM_RGBTRIPLE*) pImage->m_pPalette->m_pData;
  721. short i;
  722. // The DIB format when viewed as a IM_RGBQUAD = B|G|R|Reserved
  723. // Converting to 888 viewed as IM_RGBTRIPLE as B|G|R
  724. for (i = pDibPal->m_sStartIndex; i < pDibPal->m_sStartIndex + pDibPal->m_sNumEntries; i++)
  725. {
  726. tp888[i].rgbtBlue = qpDib[i].rgbBlue;
  727. tp888[i].rgbtGreen = qpDib[i].rgbGreen;
  728. tp888[i].rgbtRed = qpDib[i].rgbRed;
  729. }
  730. delete pDibPal;
  731. pImage->m_type = RImage::SCREEN8_888;
  732. sReturn = RImage::SCREEN8_888;
  733. break;
  734. }
  735. case RImage::SYSTEM8:
  736. case RImage::SCREEN8_555:
  737. case RImage::SCREEN8_565:
  738. {
  739. if (ConvertToBMP8(pImage) == RImage::BMP8)
  740. sReturn = ConvertToSCREEN8_888(pImage);
  741. else
  742. {
  743. TRACE("RImage::Convert - SCREEN8_888 Intermediate RImage::BMP8 translation error\n");
  744. sReturn = RImage::NOT_SUPPORTED;
  745. }
  746. break;
  747. }
  748. default:
  749. {
  750. sReturn = RImage::NOT_SUPPORTED;
  751. break;
  752. }
  753. }
  754. return sReturn;
  755. }
  756. //////////////////////////////////////////////////////////////////////
  757. //
  758. // ConvertToSCREEN16_555
  759. //
  760. // Converts from RImage::BMP8 or BMP24 to SCREEN16_555. For RImage::BMP8 it creates
  761. // a 16-bit image buffer and then dereferences the color palette for
  762. // each pixel value in the 8-bit buffer. For BMP24 it creates a 16-bit
  763. // image buffer and converts the 24-bit buffer to a 16-bit image.
  764. //
  765. //////////////////////////////////////////////////////////////////////
  766. short ConvertToSCREEN16_555(RImage* pImage)
  767. {
  768. short sReturn = RImage::NOT_SUPPORTED;
  769. switch (pImage->m_type)
  770. {
  771. case RImage::SCREEN16_555:
  772. {
  773. sReturn = RImage::SCREEN16_555;
  774. break;
  775. }
  776. case RImage::BMP8:
  777. {
  778. long r, c, height, width, pitch;
  779. // Make sure that we copy the whole thing even if the
  780. // height and width are negative values
  781. height = labs((long)pImage->m_sHeight);
  782. width = labs((long)pImage->m_sWidth);
  783. pitch = pImage->m_lPitch;
  784. // Set up pointers to the 8-bit buffer before detaching
  785. UCHAR* ucp8 = pImage->m_pData;
  786. ULONG* ulpPal = (ULONG*) pImage->m_pPalette->m_pData;
  787. // Detach the 8-bit buffer from the Image
  788. void* pDetachedMemory = pImage->DetachData();
  789. // Create a new 16-bit buffer
  790. pImage->m_sDepth = 16;
  791. pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
  792. pImage->CreateData(pImage->m_lPitch * (short)pImage->m_sHeight);
  793. USHORT* usp16 = (USHORT*) pImage->m_pData;
  794. UCHAR ucIndex;
  795. long dPitch = pImage->m_lPitch / (pImage->m_sDepth / 8);
  796. for (r = 0; r < height; r++)
  797. for (c = 0; c < width; c++)
  798. {
  799. ucIndex = ucp8[r*pitch + c];
  800. usp16[r*dPitch + c] = (USHORT) (((ulpPal[ucIndex] & 0x00f80000) >> 9) + // Red
  801. ((ulpPal[ucIndex] & 0x0000f800) >> 6) + // Green
  802. ((ulpPal[ucIndex] & 0x000000f8) >> 3)); // Blue
  803. }
  804. RImage::DestroyDetachedData(&pDetachedMemory);
  805. pImage->DestroyPalette();
  806. pImage->m_type = RImage::SCREEN16_555;
  807. sReturn = RImage::SCREEN16_555;
  808. break;
  809. }
  810. case RImage::BMP24:
  811. {
  812. long r, c, height, width, sPitch;
  813. // Make sure that we copy the whole thing even if the
  814. // height and width are negative values
  815. height = labs((long)pImage->m_sHeight);
  816. width = labs((long)pImage->m_sWidth);
  817. sPitch = pImage->m_lPitch;
  818. // Set up a pointer to the 24-bit buffer before detaching
  819. UCHAR* ucp24 = (UCHAR*) pImage->m_pData;
  820. // Detach old 24-bit buffer from the Image
  821. void* pDetachedMem = pImage->DetachData();
  822. // Create a new 16-bit buffer and set a pointer to the data
  823. pImage->m_sDepth = 16;
  824. pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
  825. pImage->CreateData(pImage->m_lPitch * (long)pImage->m_sHeight);
  826. USHORT* usp16 = (USHORT*) pImage->m_pData;
  827. long dPitch = pImage->m_lPitch / (pImage->m_sDepth / 8);
  828. for (r = 0 ; r < height; r++)
  829. for (c = 0; c < width; c++)
  830. usp16[r*dPitch + c] = (USHORT) (
  831. ((((USHORT) ucp24[r*sPitch + 3*c+2]) & 0x00f8) << 7) + // Red
  832. ((((USHORT) ucp24[r*sPitch + 3*c+1]) & 0x00f8) << 2) + // Green
  833. ((((USHORT) ucp24[r*sPitch + 3*c+0]) & 0x00f8) >> 3)); // Blue
  834. RImage::DestroyDetachedData(&pDetachedMem);
  835. pImage->m_type = RImage::SCREEN16_555;
  836. sReturn = RImage::SCREEN16_555;
  837. break;
  838. }
  839. case RImage::SYSTEM8:
  840. case RImage::SCREEN8_555:
  841. case RImage::SCREEN8_565:
  842. case RImage::SCREEN8_888:
  843. {
  844. if (ConvertToBMP8(pImage) == RImage::BMP8)
  845. sReturn = ConvertToSCREEN16_555(pImage);
  846. else
  847. {
  848. TRACE("RImage::Convert - SCREEN16_555 Intermediate RImage::BMP8 translation error\n");
  849. sReturn = RImage::NOT_SUPPORTED;
  850. }
  851. break;
  852. }
  853. case RImage::SCREEN16_565:
  854. case RImage::SCREEN24_RGB:
  855. case RImage::SCREEN32_ARGB:
  856. {
  857. if (ConvertToBMP24(pImage) == RImage::BMP24)
  858. sReturn = ConvertToSCREEN16_555(pImage);
  859. else
  860. {
  861. TRACE("RImage::Convert - SCREEN16_555 Intermediate BMP24 translation error\n");
  862. sReturn = RImage::NOT_SUPPORTED;
  863. }
  864. break;
  865. }
  866. default:
  867. {
  868. sReturn = RImage::NOT_SUPPORTED;
  869. break;
  870. }
  871. }
  872. return sReturn;
  873. }
  874. //////////////////////////////////////////////////////////////////////
  875. //
  876. // ConvertToSCREEN16_565
  877. //
  878. // Converts from RImage::BMP8 or BMP24 to SCREEN16_565. For RImage::BMP8 it creates
  879. // a 16-bit image buffer and then dereferences the color palette for
  880. // each pixel value in the 8-bit buffer. For BMP24 it creates a 16-bit
  881. // image buffer and converts the 24-bit buffer to a 16-bit image.
  882. //
  883. //////////////////////////////////////////////////////////////////////
  884. short ConvertToSCREEN16_565(RImage* pImage)
  885. {
  886. short sReturn = RImage::NOT_SUPPORTED;
  887. switch (pImage->m_type)
  888. {
  889. case RImage::SCREEN16_565:
  890. {
  891. sReturn = RImage::SCREEN16_565;
  892. break;
  893. }
  894. case RImage::BMP8:
  895. {
  896. long r, c, height, width, pitch;
  897. // Make sure that we copy the whole thing even if the
  898. // height and width are negative values
  899. height = labs((long)pImage->m_sHeight);
  900. width = labs((long)pImage->m_sWidth);
  901. pitch = pImage->m_lPitch;
  902. // Set up a pointer to the old 8-bit buffer before detaching
  903. UCHAR* ucp8 = pImage->m_pData;
  904. ULONG* ulpPal = (ULONG*) pImage->m_pPalette->m_pData;
  905. // Detach the 8-bit buffer from the Image
  906. void* pDetachedMem = pImage->DetachData();
  907. // Create a new 16-bit buffer and set pointers to the data
  908. pImage->m_sDepth = 16;
  909. pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
  910. pImage->CreateData(pImage->m_lPitch * (long)pImage->m_sHeight);
  911. USHORT* usp16 = (USHORT*) pImage->m_pData;
  912. UCHAR ucIndex;
  913. long dPitch = pImage->m_lPitch / (pImage->m_sDepth/8);
  914. for (r = 0; r < height; r++)
  915. for (c = 0; c < width; c++)
  916. {
  917. ucIndex = ucp8[r*pitch + c];
  918. usp16[r*dPitch + c] = (USHORT) (((ulpPal[ucIndex] & 0x00f80000) >> 8) + // Red
  919. ((ulpPal[ucIndex] & 0x0000fc00) >> 5) + // Green
  920. ((ulpPal[ucIndex] & 0x000000f8) >> 3)); // Blue
  921. }
  922. RImage::DestroyDetachedData(&pDetachedMem);
  923. pImage->DestroyPalette();
  924. pImage->m_type = RImage::SCREEN16_565;
  925. sReturn = RImage::SCREEN16_565;
  926. break;
  927. }
  928. case RImage::BMP24:
  929. {
  930. long r, c, height, width, sPitch;
  931. // Make sure that we copy the whole thing even if the
  932. // height and width are negative values
  933. height = labs((long)pImage->m_sHeight);
  934. width = labs((long)pImage->m_sWidth);
  935. sPitch = pImage->m_lPitch;
  936. // Set a pointer to the 24-bit buffer before detaching
  937. UCHAR* ucp24 = (UCHAR*) pImage->m_pData;
  938. // Detach the 24-bit buffer from the Image
  939. void* pDetachedMem = pImage->DetachData();
  940. // Create a new 16-bit buffer and set a pointer to the data
  941. pImage->m_sDepth = 16;
  942. pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
  943. pImage->CreateData(pImage->m_lPitch * (long)pImage->m_sHeight);
  944. USHORT* usp16 = (USHORT*) pImage->m_pData;
  945. long dPitch = pImage->m_lPitch / (pImage->m_sDepth / 8);
  946. for (r = 0 ; r < height; r++)
  947. for (c = 0; c < width; c++)
  948. usp16[r*dPitch + c] = (USHORT) (
  949. ((((USHORT) ucp24[r*sPitch + 3*c+2]) & 0x00f8) << 8) + // Red
  950. ((((USHORT) ucp24[r*sPitch + 3*c+1]) & 0x00fc) << 3) + // Green
  951. ((((USHORT) ucp24[r*sPitch + 3*c+0]) & 0x00f8) >> 3)); // Blue
  952. RImage::DestroyDetachedData(&pDetachedMem);
  953. pImage->m_type = RImage::SCREEN16_565;
  954. sReturn = RImage::SCREEN16_565;
  955. break;
  956. }
  957. case RImage::SYSTEM8:
  958. case RImage::SCREEN8_555:
  959. case RImage::SCREEN8_565:
  960. case RImage::SCREEN8_888:
  961. {
  962. if (ConvertToBMP8(pImage) == RImage::BMP8)
  963. sReturn = ConvertToSCREEN16_565(pImage);
  964. else
  965. {
  966. TRACE("RImage::Convert - SCREEN16_565 Intermediate RImage::BMP8 translation error\n");
  967. sReturn = RImage::NOT_SUPPORTED;
  968. }
  969. break;
  970. }
  971. case RImage::SCREEN16_555:
  972. case RImage::SCREEN24_RGB:
  973. case RImage::SCREEN32_ARGB:
  974. {
  975. if (ConvertToBMP24(pImage) == RImage::BMP24)
  976. sReturn = ConvertToSCREEN16_565(pImage);
  977. else
  978. {
  979. TRACE("RImage::Convert - SCREEN16_565 Intermediate BMP24 translation error\n");
  980. sReturn = RImage::NOT_SUPPORTED;
  981. }
  982. break;
  983. }
  984. default:
  985. {
  986. sReturn = RImage::NOT_SUPPORTED;
  987. break;
  988. }
  989. }
  990. return sReturn;
  991. }
  992. //////////////////////////////////////////////////////////////////////
  993. //
  994. // ConvertToSCREEN24_RGB
  995. //
  996. // Converts from RImage::BMP8 or BMP24 to SCREEN32_RGB. For RImage::BMP8 it creates
  997. // a 24-bit buffer and then dereferences the color palette for each
  998. // pixel value in the 8-bit buffer. For BMP24 it is already in the
  999. // correct format and just changes the image type.
  1000. //
  1001. //////////////////////////////////////////////////////////////////////
  1002. short ConvertToSCREEN24_RGB(RImage* pImage)
  1003. {
  1004. short sReturn = RImage::NOT_SUPPORTED;
  1005. switch (pImage->m_type)
  1006. {
  1007. case RImage::SCREEN24_RGB:
  1008. {
  1009. sReturn = RImage::SCREEN24_RGB;
  1010. break;
  1011. }
  1012. case RImage::BMP8:
  1013. {
  1014. long r, c, height, width, sPitch, dPitch;
  1015. // Make sure that we copy the whole thing even if the
  1016. // height and width are negative values
  1017. height = labs((long)pImage->m_sHeight);
  1018. width = labs((long)pImage->m_sWidth);
  1019. sPitch = pImage->m_lPitch;
  1020. // Set up a pointer to the 8-bit buffer before detaching
  1021. UCHAR* ucp8 = pImage->m_pData;
  1022. ULONG* ulPal = (ULONG*) pImage->m_pPalette->m_pData;
  1023. // Detach the 8-bit buffer from the Image
  1024. void* pDetachedMem = pImage->DetachData();
  1025. // Create a new 24-bit buffer and set a pointer to the data
  1026. pImage->m_sDepth = 24;
  1027. dPitch = pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
  1028. pImage->CreateData(pImage->m_lPitch * (long)pImage->m_sHeight);
  1029. UCHAR* ucp24 = (UCHAR*) pImage->m_pData;
  1030. ULONG ulColor;
  1031. for (r = 0; r < height; r++)
  1032. for (c = 0; c < width; c++)
  1033. {
  1034. ulColor = ulPal[ucp8[r*sPitch + c]];
  1035. ucp24[r*dPitch + 3*c+0] = (UCHAR) (ulColor & 0x000000ff);
  1036. ucp24[r*dPitch + 3*c+1] = (UCHAR) ((ulColor & 0x0000ff00) / 0x100);
  1037. ucp24[r*dPitch + 3*c+2] = (UCHAR) ((ulColor & 0x00ff0000) / 0x10000);
  1038. }
  1039. RImage::DestroyDetachedData(&pDetachedMem);
  1040. pImage->DestroyPalette();
  1041. pImage->m_type = RImage::SCREEN24_RGB;
  1042. sReturn = RImage::SCREEN24_RGB;
  1043. break;
  1044. }
  1045. case RImage::BMP24:
  1046. {
  1047. pImage->m_type = RImage::SCREEN24_RGB;
  1048. sReturn = RImage::SCREEN24_RGB;
  1049. break;
  1050. }
  1051. case RImage::SYSTEM8:
  1052. case RImage::SCREEN8_555:
  1053. case RImage::SCREEN8_565:
  1054. case RImage::SCREEN8_888:
  1055. {
  1056. if (ConvertToBMP8(pImage) == RImage::BMP8)
  1057. sReturn = ConvertToSCREEN24_RGB(pImage);
  1058. else
  1059. {
  1060. TRACE("RImage::Convert - SCREEN24_RGB Intermediate RImage::BMP8 translation error\n");
  1061. sReturn = RImage::NOT_SUPPORTED;
  1062. }
  1063. break;
  1064. }
  1065. case RImage::SCREEN16_555:
  1066. case RImage::SCREEN16_565:
  1067. case RImage::SCREEN32_ARGB:
  1068. {
  1069. if (ConvertToBMP24(pImage) == RImage::BMP24)
  1070. sReturn = ConvertToSCREEN24_RGB(pImage);
  1071. else
  1072. {
  1073. TRACE("RImage::Convert - SCREEN24_RGB Intermediate BMP24 translation error\n");
  1074. sReturn = RImage::NOT_SUPPORTED;
  1075. }
  1076. break;
  1077. }
  1078. default:
  1079. {
  1080. sReturn = RImage::NOT_SUPPORTED;
  1081. break;
  1082. }
  1083. }
  1084. return sReturn;
  1085. }
  1086. //////////////////////////////////////////////////////////////////////
  1087. //
  1088. // ConvertToSCREEN32_ARGB
  1089. //
  1090. // Converts from RImage::BMP8 or BMP24 to SCREEN32_RGBA. For RImage::BMP8 it creates
  1091. // a 32-bit buffer and then dereferences the color palette for each
  1092. // pixel value in the 8-bit buffer. For BMP24 it creates a 32-bit
  1093. // buffer and then translates the IM_RGBQUAD pixel values into RGBAlpha
  1094. // "Screen Format" pixel values.
  1095. //
  1096. //////////////////////////////////////////////////////////////////////
  1097. short ConvertToSCREEN32_ARGB(RImage* pImage)
  1098. {
  1099. short sReturn = RImage::NOT_SUPPORTED;
  1100. switch (pImage->m_type)
  1101. {
  1102. case RImage::SCREEN32_ARGB:
  1103. {
  1104. sReturn = RImage::SCREEN32_ARGB;
  1105. break;
  1106. }
  1107. case RImage::BMP8:
  1108. {
  1109. long r, c, height, width, pitch;
  1110. // Make sure that we copy the whole thing even if the
  1111. // height and width are negative values
  1112. height = labs((long)pImage->m_sHeight);
  1113. width = labs((long)pImage->m_sWidth);
  1114. pitch = pImage->m_lPitch;
  1115. // Set up a pointer to the 8-bit buffer before detaching
  1116. UCHAR* ucp8 = pImage->m_pData;
  1117. ULONG* ulPal = (ULONG*) pImage->m_pPalette->m_pData;
  1118. // Detach the 8-bit buffer from the Image
  1119. void* pDetachedMem = pImage->DetachData();
  1120. // Create a new 32-bit buffer and set a pointer to the data
  1121. pImage->m_sDepth = 32;
  1122. pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
  1123. pImage->CreateData(pImage->m_lPitch * (long)pImage->m_sHeight);
  1124. ULONG* ulp32 = (ULONG*) pImage->m_pData;
  1125. long dLongPitch = pImage->m_lPitch/4;
  1126. for (r = 0; r < height; r++)
  1127. for (c = 0; c < width; c++)
  1128. ulp32[r*dLongPitch + c] = ulPal[ucp8[r*pitch + c]];
  1129. RImage::DestroyDetachedData(&pDetachedMem);
  1130. pImage->DestroyPalette();
  1131. pImage->m_type = RImage::SCREEN32_ARGB;
  1132. sReturn = RImage::SCREEN32_ARGB;
  1133. break;
  1134. }
  1135. case RImage::BMP24:
  1136. {
  1137. long r, c, height, width, sPitch;
  1138. // Make sure that we copy the whole thing even if the
  1139. // height and width are negative values
  1140. height = labs((long)pImage->m_sHeight);
  1141. width = labs((long)pImage->m_sWidth);
  1142. sPitch = pImage->m_lPitch;
  1143. // Set a pointer to the 24-bit buffer before detaching
  1144. UCHAR* ucp24 = (UCHAR*) pImage->m_pData;
  1145. // Detach the 24-bit buffer from the Image
  1146. void* pDetachedMem = pImage->DetachData();
  1147. // Create a new 32-bit buffer and set a pointer to the data
  1148. pImage->m_sDepth = 32;
  1149. pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
  1150. pImage->CreateData(pImage->m_lPitch * (long)pImage->m_sHeight);
  1151. ULONG* ulp32 = (ULONG*) pImage->m_pData;
  1152. long dLongPitch = pImage->m_lPitch/4;
  1153. for (r = 0 ; r < height; r++)
  1154. for (c = 0; c < width; c++)
  1155. ulp32[r*dLongPitch + c] = (ULONG) (
  1156. ((ULONG) ucp24[r*sPitch + 3*c+2] * 0x10000) +
  1157. ((ULONG) ucp24[r*sPitch + 3*c+1] * 0x100) +
  1158. ((ULONG) ucp24[r*sPitch + 3*c+0])) ;
  1159. RImage::DestroyDetachedData(&pDetachedMem);
  1160. pImage->m_type = RImage::SCREEN32_ARGB;
  1161. sReturn = RImage::SCREEN32_ARGB;
  1162. break;
  1163. }
  1164. case RImage::SYSTEM8:
  1165. case RImage::SCREEN8_555:
  1166. case RImage::SCREEN8_565:
  1167. case RImage::SCREEN8_888:
  1168. {
  1169. if (ConvertToBMP8(pImage) == RImage::BMP8)
  1170. sReturn = ConvertToSCREEN32_ARGB(pImage);
  1171. else
  1172. {
  1173. TRACE("RImage::Convert - SCREEN32_ARGB Intermediate RImage::BMP8 translation error\n");
  1174. sReturn = RImage::NOT_SUPPORTED;
  1175. }
  1176. break;
  1177. }
  1178. case RImage::SCREEN16_555:
  1179. case RImage::SCREEN16_565:
  1180. case RImage::SCREEN24_RGB:
  1181. {
  1182. if (ConvertToBMP24(pImage) == RImage::BMP24)
  1183. sReturn = ConvertToSCREEN32_ARGB(pImage);
  1184. else
  1185. {
  1186. TRACE("RImage::Convert - SCREEN32_ARGB Intermediate BMP24 translation error\n");
  1187. sReturn = RImage::NOT_SUPPORTED;
  1188. }
  1189. break;
  1190. }
  1191. default:
  1192. {
  1193. sReturn = RImage::NOT_SUPPORTED;
  1194. break;
  1195. }
  1196. }
  1197. return sReturn;
  1198. }
  1199. //////////////////////////////////////////////////////////////////////
  1200. //
  1201. // Converts from the Window's compression format for 8 bit BMPs (RLE8)
  1202. // RImage::BMP8RLE to RImage::BMP8 format. Palette is not touched.
  1203. //
  1204. // Description of this process from Win32 documentation:
  1205. // This format can be compressed in encoded or absolute modes. Both
  1206. // modes can occur anywhere in the same bitmap.
  1207. // · Encoded mode consists of two bytes: the first byte specifies the
  1208. // number of consecutive pixels to be drawn using the color index
  1209. // contained in the second byte. In addition, the first byte of the pair
  1210. // can be set to zero to indicate an escape that denotes an end of line,
  1211. // end of bitmap, or delta. The interpretation of the escape depends on
  1212. // the value of the second byte of the pair, which can be one of the
  1213. // following:
  1214. //
  1215. // Value Meaning
  1216. //
  1217. // 0 End of line.
  1218. // 1 End of bitmap.
  1219. // 2 Delta. The two bytes following the escape contain unsigned values
  1220. // indicating the horizontal and vertical offsets of the next pixel from
  1221. // the current position.
  1222. //
  1223. // · In absolute mode, the first byte is zero and the second byte is a
  1224. // value in the range 03H through FFH. The second byte represents the
  1225. // number of bytes that follow, each of which contains the color index
  1226. // of a single pixel. When the second byte is 2 or less, the escape has
  1227. // the same meaning as in encoded mode. In absolute mode, each run must
  1228. // be aligned on a word boundary.
  1229. //
  1230. //
  1231. //////////////////////////////////////////////////////////////////////
  1232. short ConvertFromBMP8RLE(RImage* pImage)
  1233. {
  1234. short sRes = RImage::NOT_SUPPORTED; // Assume failure.
  1235. ASSERT(pImage->m_type == RImage::BMP8RLE);
  1236. // Set up a pointer to the 8-bit compressed buffer before detaching
  1237. U8* pu8Comp = pImage->m_pData;
  1238. U8* pu8End = pu8Comp + pImage->m_ulSize;
  1239. // Detach the 8-bit compressed buffer from the Image
  1240. void* pvDetachedMem = pImage->DetachData();
  1241. // Create a new 8-bit uncompressed buffer and set a pointer to the
  1242. // data. Leave the current pitch.
  1243. if (pImage->CreateData(pImage->m_lPitch * (long)pImage->m_sHeight) == 0)
  1244. {
  1245. U8* pu8Uncomp = pImage->m_pData;
  1246. // We must flip the image during decompression.
  1247. // This should work for both negative and positive
  1248. // pitch buffers (i.e., upside down and right side up).
  1249. long lPitch = -pImage->m_lPitch;
  1250. pu8Uncomp = pu8Uncomp + pImage->m_lPitch * ((long)pImage->m_sHeight - 1);
  1251. U8* pu8Row = pu8Uncomp;
  1252. // Actual decompression. See function header for details.
  1253. U8 u8Num; // Num pixels to run.
  1254. U8 u8Pixel; // Pixel to run.
  1255. short sDone = FALSE;
  1256. while (sDone == FALSE && pu8Comp < pu8End)
  1257. {
  1258. // First byte is number of pixels to run, if not 0.
  1259. u8Num = *pu8Comp++;
  1260. if (u8Num > 0)
  1261. {
  1262. // Second byte is the pixel to run the u8Num pixels.
  1263. u8Pixel = *pu8Comp++;
  1264. // Intrinsic version of this should be faster than C.
  1265. memset(pu8Uncomp, u8Pixel, u8Num);
  1266. pu8Uncomp += u8Num;
  1267. }
  1268. else
  1269. {
  1270. // The number of bytes is 0, this is an "escape" or
  1271. // absolute mode.
  1272. // Second byte is the type of escape, unless 3 or more
  1273. // which indicates the number of absolute bytes to copy.
  1274. u8Num = *pu8Comp++;
  1275. switch (u8Num)
  1276. {
  1277. case 0: // End of line.
  1278. // Move to next line of destination.
  1279. // We require these end of lines for correct decompression.
  1280. pu8Row += lPitch;
  1281. pu8Uncomp = pu8Row;
  1282. break;
  1283. case 1: // End of bitmap.
  1284. sDone = TRUE;
  1285. break;
  1286. case 2:
  1287. {
  1288. // Move to position indicated by next two bytes relative
  1289. // to this position. Horizontal first, vertical second.
  1290. // This should only be used in the case of deltas and
  1291. // I cannot see how that could ever be since this isn't
  1292. // an animation format.
  1293. U8 u8Horz = *pu8Comp++;
  1294. U8 u8Vert = *pu8Comp++;
  1295. pu8Uncomp += u8Horz + (u8Vert * lPitch);
  1296. break;
  1297. }
  1298. default: // Absolute mode.
  1299. // Intrinsic version of memcpy is fast; it aligns its copies
  1300. // unless the compiler sucks.
  1301. memcpy(pu8Uncomp, pu8Comp, u8Num);
  1302. pu8Comp += u8Num;
  1303. pu8Uncomp += u8Num;
  1304. // This copy is supposed to be word aligned. It is not clearly
  1305. // stated in the dox, but it seems that, if this was an odd
  1306. // number of bytes, we should skip the next byte.
  1307. if (u8Num % 2 != 0)
  1308. {
  1309. pu8Comp++;
  1310. }
  1311. break;
  1312. }
  1313. }
  1314. }
  1315. // Deallocate old buffer.
  1316. RImage::DestroyDetachedData(&pvDetachedMem);
  1317. pImage->m_type = RImage::BMP8;
  1318. sRes = (short)pImage->m_type;
  1319. }
  1320. else
  1321. {
  1322. TRACE("ConvertFromBMP8RLE(): CreateData() failed.\n");
  1323. // Re-attach old buffer.
  1324. pImage->m_pMem = (UCHAR*)pvDetachedMem;
  1325. }
  1326. return sRes;
  1327. }
  1328. //////////////////////////////////////////////////////////////////////
  1329. //
  1330. // Converts to the Window's compression format for 8 bit BMPs (RLE8)
  1331. // RImage::BMP8RLE from RImage::BMP8. Palette is not touched. See
  1332. // description of this compression in comment header for
  1333. // ConvertFromBMP8RLE.
  1334. //
  1335. //////////////////////////////////////////////////////////////////////
  1336. short ConvertToBMP8RLE(RImage* pImage)
  1337. {
  1338. short sRes = RImage::NOT_SUPPORTED; // Assume failure.
  1339. // Only certain types can be converted from.
  1340. switch (pImage->m_type)
  1341. {
  1342. case RImage::BMP8:
  1343. {
  1344. // Set up a pointer to the 8-bit uncompressed buffer before detaching
  1345. U8* pu8Uncomp = pImage->m_pData;
  1346. // We must flip the image during compression.
  1347. // This should work for both negative and positive
  1348. // pitch buffers (i.e., upside down and right side up).
  1349. long lPitch = -pImage->m_lPitch;
  1350. pu8Uncomp = pu8Uncomp + pImage->m_lPitch * ((long)pImage->m_sHeight - 1);
  1351. // Detach the 8-bit uncompressed buffer from the Image
  1352. void* pvDetachedMem = pImage->DetachData();
  1353. // Create a new 8-bit compressed buffer and set a pointer to the
  1354. // data. Leave the current pitch. This buffer must be big enough for
  1355. // the worst case compression (it could be infinitely large if I were
  1356. // dumb and added many deltas that didn't do anything, but I won't
  1357. // do that). I think the worst case for my algorithm is a run of 1 pixel
  1358. // followed by a run of 1 different pixel, followed by a run of 1 or more
  1359. // pixels different than the previous run. That's 6 bytes for 3 pixels?
  1360. // plus end of lines, which 1 to 1 for the height. Therefore, I'm
  1361. // assuming 2 times the pixels plus the height times 2 (2 bytes for each end
  1362. // of line) plus 2 bytes for the end of bitmap is good enough.
  1363. // 2 * ulSize + lHeight * 2 + 2.
  1364. if (pImage->CreateData(2 * pImage->m_ulSize + (long)pImage->m_sHeight * 2 + 2) == 0)
  1365. {
  1366. U8* pu8Comp = pImage->m_pData;
  1367. // Actual compression. See function header for details.
  1368. U8* pu8Row = pu8Uncomp;
  1369. long lRowRemain;
  1370. long lRun;
  1371. // Compress until we exceed buffer. Nothing has explicitly
  1372. // said we should, but we will try to be row based. This works
  1373. // well for flipping the image while we're compressing.
  1374. // Note that we never use the escape for moving the current position.
  1375. // It seems to me this would only be useful in animation.
  1376. for (long lNumLines = (long)pImage->m_sHeight; lNumLines > 0; lNumLines--)
  1377. {
  1378. lRowRemain = (long)pImage->m_sWidth;
  1379. while (lRowRemain > 0)
  1380. {
  1381. // Look for verbatim runs first since they are limited
  1382. // to 3 or more.
  1383. for (lRun = 1; lRun < lRowRemain && lRun < 255; lRun++)
  1384. {
  1385. if (pu8Uncomp[lRun] == pu8Uncomp[lRun - 1])
  1386. {
  1387. break;
  1388. }
  1389. }
  1390. // If less than 3, do a one color run . . .
  1391. if (lRun < 3)
  1392. {
  1393. // Look for length of run with one color index.
  1394. for (lRun = 1; lRun < lRowRemain && lRun < 255; lRun++)
  1395. {
  1396. if (pu8Uncomp[lRun] != *pu8Uncomp)
  1397. {
  1398. break;
  1399. }
  1400. }
  1401. // Number of pixels to run this color index.
  1402. *pu8Comp++ = (U8)lRun;
  1403. // Color index to run.
  1404. *pu8Comp++ = *pu8Uncomp;
  1405. // Advance past run.
  1406. pu8Uncomp += lRun;
  1407. }
  1408. else
  1409. {
  1410. // 0 indicates "absolute mode".
  1411. *pu8Comp++ = 0;
  1412. // Number of absolute pixels.
  1413. *pu8Comp++ = (U8)lRun;
  1414. // Verbatim run.
  1415. memcpy(pu8Comp, pu8Uncomp, lRun);
  1416. // Advance uncomp.
  1417. pu8Uncomp += lRun;
  1418. // Advance comp.
  1419. pu8Comp += lRun;
  1420. // If this is an odd number . . .
  1421. if ((lRun % 2) == 1)
  1422. {
  1423. // Skip to maintain "word align"ment. Make
  1424. // ignored byte 0 for obviousness.
  1425. *pu8Comp++ = 0;
  1426. }
  1427. }
  1428. // Reduce amount left this row.
  1429. lRowRemain -= lRun;
  1430. ASSERT(lRowRemain >= 0);
  1431. }
  1432. // Add end of line escape.
  1433. *pu8Comp++ = 0;
  1434. *pu8Comp++ = 0;
  1435. // Update row.
  1436. pu8Row += lPitch;
  1437. // Set ptr to new row.
  1438. pu8Uncomp = pu8Row;
  1439. }
  1440. // Add end of BMP escape.
  1441. *pu8Comp++ = 0;
  1442. *pu8Comp++ = 1;
  1443. // Get size of compressed buffer.
  1444. ULONG ulSize = (pu8Comp - pImage->m_pData);
  1445. // Deallocate old buffer.
  1446. RImage::DestroyDetachedData(&pvDetachedMem);
  1447. // Allocate again and copy.
  1448. pu8Comp = pImage->m_pData;
  1449. pvDetachedMem = pImage->DetachData();
  1450. // Attempt to allocate new correctly sized buffer . . .
  1451. if (pImage->CreateData(ulSize) == 0)
  1452. {
  1453. // Copy data.
  1454. memcpy(pImage->m_pData, pu8Comp, pImage->m_ulSize);
  1455. // Destroy old, too large compressed buffer.
  1456. RImage::DestroyDetachedData(&pvDetachedMem);
  1457. }
  1458. else
  1459. {
  1460. TRACE("ConvertToBMP8RLE(): CreateData() failed for second compressed buffer.\n");
  1461. // Re-attach old buffer.
  1462. pImage->m_pMem = (UCHAR*)pvDetachedMem;
  1463. }
  1464. pImage->m_type = RImage::BMP8RLE;
  1465. sRes = (short)pImage->m_type;
  1466. }
  1467. else
  1468. {
  1469. TRACE("ConvertToBMP8RLE(): CreateData() failed.\n");
  1470. // Re-attach old buffer.
  1471. pImage->m_pMem = (UCHAR*)pvDetachedMem;
  1472. }
  1473. break;
  1474. }
  1475. default:
  1476. // Not supported.
  1477. break;
  1478. }
  1479. return sRes;
  1480. }
  1481. //////////////////////////////////////////////////////////////////////
  1482. //
  1483. // Converts from RImage::BMP1 to RImage::BMP8. Palette is not touched, but
  1484. // is NOT significant to BMP1 format (1 == Black, 0 == White).
  1485. //
  1486. //////////////////////////////////////////////////////////////////////
  1487. short ConvertFromBMP1(RImage* pImage)
  1488. {
  1489. short sRes = RImage::NOT_SUPPORTED; // Assume failure.
  1490. // Set up a pointer to the 1-bit packed buffer before detaching.
  1491. U8* pu8Src = pImage->m_pData;
  1492. // Detach the 1-bit packed buffer from the Image
  1493. void* pvDetachedMem = pImage->DetachData();
  1494. // Create a new 8-bit buffer and set a pointer to the
  1495. // data. Alter the current pitch.
  1496. // Set new depth.
  1497. pImage->m_sDepth = 8;
  1498. // Remember old pitch.
  1499. long lSrcPitch = pImage->m_lPitch;
  1500. // Compute the new pitch. Preserve sign.
  1501. if (pImage->m_lPitch > 0)
  1502. {
  1503. pImage->m_lPitch = RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
  1504. }
  1505. else
  1506. {
  1507. pImage->m_lPitch = -RImage::GetPitch(pImage->m_sWidth, pImage->m_sDepth);
  1508. }
  1509. // Allocate new data. This call sets ulSize. Preserve m_sWidth, m_sHeight.
  1510. if (pImage->CreateData(pImage->m_sHeight * ABS(pImage->m_lPitch)) == 0)
  1511. {
  1512. // Destination.
  1513. U8* pu8Dst = pImage->m_pData;
  1514. // Row trackers.
  1515. U8* pu8SrcRow = pu8Src;
  1516. U8* pu8DstRow = pu8Dst;
  1517. long lRows = (long)pImage->m_sHeight;
  1518. long lCols;
  1519. while (lRows-- > 0)
  1520. {
  1521. lCols = (long)pImage->m_sWidth / 8;
  1522. while (lCols-- > 0)
  1523. {
  1524. // Pack a byte.
  1525. *pu8Dst++ = *pu8Src >> 7;
  1526. *pu8Dst++ = (*pu8Src & 0x40) >> 6;
  1527. *pu8Dst++ = (*pu8Src & 0x20) >> 5;
  1528. *pu8Dst++ = (*pu8Src & 0x10) >> 4;
  1529. *pu8Dst++ = (*pu8Src & 0x08) >> 3;
  1530. *pu8Dst++ = (*pu8Src & 0x04) >> 2;
  1531. *pu8Dst++ = (*pu8Src & 0x02) >> 1;
  1532. *pu8Dst++ = (*pu8Src++ & 0x01);
  1533. }
  1534. // Move "down" a row.
  1535. pu8SrcRow += lSrcPitch;
  1536. pu8DstRow += pImage->m_lPitch;
  1537. // Update columns to beginning of row.
  1538. pu8Src = pu8SrcRow;
  1539. pu8Dst = pu8DstRow;
  1540. }
  1541. // Deallocate old buffer.
  1542. RImage::DestroyDetachedData(&pvDetachedMem);
  1543. // Set new type.
  1544. pImage->m_type = RImage::BMP8;
  1545. // Set return value.
  1546. sRes = (short)pImage->m_type;
  1547. }
  1548. else
  1549. {
  1550. TRACE("ConvertToBMP1(): CreateData() failed.\n");
  1551. // Re-attach old buffer.
  1552. pImage->m_pMem = (UCHAR*)pvDetachedMem;
  1553. }
  1554. return sRes;
  1555. }
  1556. //////////////////////////////////////////////////////////////////////
  1557. //
  1558. // Converts to RImage::BMP1 from RImage::BMP8. Palette is not touched, but
  1559. // is NOT significant to this format (1 == Black, 0 == White).
  1560. //
  1561. //////////////////////////////////////////////////////////////////////
  1562. short ConvertToBMP1(RImage* pImage)
  1563. {
  1564. short sRes = RImage::NOT_SUPPORTED; // Assume failure.
  1565. // Only certain types can be converted from.
  1566. switch (pImage->m_type)
  1567. {
  1568. case RImage::BMP8:
  1569. {
  1570. // Set up a pointer to the 8-bit buffer before detaching.
  1571. U8* pu8Src = pImage->m_pData;
  1572. // Detach the 8-bit buffer from the Image
  1573. void* pvDetachedMem = pImage->DetachData();
  1574. // Create a new 1-bit packed buffer and set a pointer to the
  1575. // data. Alter the current pitch.
  1576. // Set new depth.
  1577. pImage->m_sDepth = 1;
  1578. // Remember old pitch.
  1579. long lSrcPitch = pImage->m_lPitch;
  1580. // If there is a partial byte . . .
  1581. if ((pImage->m_lPitch % 8) != 0)
  1582. {
  1583. pImage->m_lPitch = (pImage->m_lPitch / 8);
  1584. // Adjust appropriately for positive pitch . . .
  1585. if (pImage->m_lPitch > 0)
  1586. {
  1587. pImage->m_lPitch++;
  1588. }
  1589. else // Negative pitch.
  1590. {
  1591. pImage->m_lPitch--;
  1592. }
  1593. }
  1594. else
  1595. {
  1596. pImage->m_lPitch = (pImage->m_lPitch / 8);
  1597. }
  1598. // Allocate new data. This call sets ulSize. Preserve lWidth, lHeight.
  1599. if (pImage->CreateData((long)pImage->m_sHeight * ABS(pImage->m_lPitch)) == 0)
  1600. {
  1601. // Bit packed destination.
  1602. U8* pu8Dst = pImage->m_pData;
  1603. // Row trackers.
  1604. U8* pu8SrcRow = pu8Src;
  1605. U8* pu8DstRow = pu8Dst;
  1606. // Converts non-zero values to a 1 and increments ptr.
  1607. #define CHECK_NONZERO_INC(p) ((*(p)++ == 0) ? 0 : 1)
  1608. long lRows = (long)pImage->m_sHeight;
  1609. long lCols;
  1610. while (lRows-- > 0)
  1611. {
  1612. lCols = (long)pImage->m_sWidth / 8;
  1613. while (lCols-- > 0)
  1614. {
  1615. // Pack a byte.
  1616. *pu8Dst = CHECK_NONZERO_INC(pu8Src) << 7;
  1617. *pu8Dst |= CHECK_NONZERO_INC(pu8Src) << 6;
  1618. *pu8Dst |= CHECK_NONZERO_INC(pu8Src) << 5;
  1619. *pu8Dst |= CHECK_NONZERO_INC(pu8Src) << 4;
  1620. *pu8Dst |= CHECK_NONZERO_INC(pu8Src) << 3;
  1621. *pu8Dst |= CHECK_NONZERO_INC(pu8Src) << 2;
  1622. *pu8Dst |= CHECK_NONZERO_INC(pu8Src) << 1;
  1623. *pu8Dst++ |= CHECK_NONZERO_INC(pu8Src) << 0;
  1624. }
  1625. // Move "down" a row.
  1626. pu8SrcRow += lSrcPitch;
  1627. pu8DstRow += pImage->m_lPitch;
  1628. // Update columns to beginning of row.
  1629. pu8Src = pu8SrcRow;
  1630. pu8Dst = pu8DstRow;
  1631. }
  1632. // Deallocate old buffer.
  1633. RImage::DestroyDetachedData(&pvDetachedMem);
  1634. // Set new type.
  1635. pImage->m_type = RImage::BMP1;
  1636. // Set return value.
  1637. sRes = (short)pImage->m_type;
  1638. }
  1639. else
  1640. {
  1641. TRACE("ConvertToBMP1(): CreateData() failed.\n");
  1642. // Re-attach old buffer.
  1643. pImage->m_pMem = (UCHAR*)pvDetachedMem;
  1644. }
  1645. break;
  1646. }
  1647. default:
  1648. // Not supported.
  1649. break;
  1650. }
  1651. return sRes;
  1652. }
  1653. //////////////////////////////////////////////////////////////////////
  1654. // EOF
  1655. //////////////////////////////////////////////////////////////////////