ImageFile.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  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. // ImageFile.CPP
  21. //
  22. // History:
  23. // 12/11/96 JMI Started.
  24. //
  25. // 12/19/96 JMI Took out comment regarding adding a version to LOADFUNC.
  26. //
  27. // 02/04/97 JMI Changed #include "ImageLoad.h" to "ImageFile.h".
  28. //
  29. // 02/04/97 JMI Now RImageFile::Load() will invoke RImage->LoadDib() for
  30. // BMP formatted files.
  31. //
  32. //////////////////////////////////////////////////////////////////////////////
  33. //
  34. // Handles file formats for RImage. Some of these older formats will not be
  35. // useful to developers of new code. To include the ability to use a certain
  36. // loader, define one of the macros IMAGE_LOAD_# where # is the number of the
  37. // format desired OR define the macro IMAGE_LOAD_ALL for all available
  38. // support.
  39. //
  40. // NOTES TO THOSE ADDING NEW FILE VERSIONS:
  41. // Please follow these steps when adding a new version Load or Save:
  42. // o Define a new static short RImageFile::LoadVersion#(RImage*, RFile*)
  43. // where # is the number of the new version.
  44. //
  45. // o Call your new LoadVersion#(...) in the switch statement in
  46. // RImageFile::Load().
  47. //
  48. // o Make sure the last versions' case in the switch is surrounded by a
  49. // #if defined(IMAGE_LOAD_num) #endif block where 'num' is the last version
  50. // number.
  51. //
  52. //
  53. //////////////////////////////////////////////////////////////////////////////
  54. //////////////////////////////////////////////////////////////////////////////
  55. // C Headers -- Must be included before RSPiX.h b/c RSPiX utilizes SHMalloc.
  56. //////////////////////////////////////////////////////////////////////////////
  57. ///////////////////////////////////////////////////////////////////////////////
  58. // RSPiX Headers.
  59. // If PATHS_IN_INCLUDES macro is defined, we can utilize relative
  60. // paths to a header file. In this case we generally go off of our
  61. // RSPiX root directory. System.h MUST be included before this macro
  62. // is evaluated. System.h is the header that, based on the current
  63. // platform (or more so in this case on the compiler), defines
  64. // PATHS_IN_INCLUDES. Blue.h includes system.h so you can include that
  65. // instead.
  66. ///////////////////////////////////////////////////////////////////////////////
  67. #include "System.h"
  68. #ifdef PATHS_IN_INCLUDES
  69. #include "GREEN/Image/Image.h"
  70. #include "GREEN/Image/ImageFile.h"
  71. #include "GREEN/Image/PalFile.h"
  72. #else
  73. #include "Image.h"
  74. #include "ImageFile.h"
  75. #include "PalFile.h"
  76. #endif
  77. //////////////////////////////////////////////////////////////////////////////
  78. // Module specific macros.
  79. //////////////////////////////////////////////////////////////////////////////
  80. //////////////////////////////////////////////////////////////////////////////
  81. // Module specific typedefs.
  82. //////////////////////////////////////////////////////////////////////////////
  83. //////////////////////////////////////////////////////////////////////////////
  84. // Exported (extern) variables.
  85. //////////////////////////////////////////////////////////////////////////////
  86. //////////////////////////////////////////////////////////////////////////////
  87. // Module specific (static) variables / Instantiate class statics.
  88. //////////////////////////////////////////////////////////////////////////////
  89. //////////////////////////////////////////////////////////////////////////////
  90. // Module specific (static) protos.
  91. //////////////////////////////////////////////////////////////////////////////
  92. //////////////////////////////////////////////////////////////////////////////
  93. // Internal Functions.
  94. //////////////////////////////////////////////////////////////////////////////
  95. //////////////////////////////////////////////////////////////////////////////
  96. //
  97. // Loads an RImage with file version 1 into pim from pfile.
  98. //
  99. //////////////////////////////////////////////////////////////////////////////
  100. short RImageFile::LoadVersion1( // Returns SUCCESS on success or FAILURE on
  101. // failure.
  102. RImage* /*pim*/, // Image to load into.
  103. RFile* /*pfile*/) // File to load from.
  104. {
  105. short sRes = SUCCESS; // Assume success.
  106. TRACE("LoadVersion1(): No current support for version 1 RImage.\n");
  107. sRes = FAILURE;
  108. return sRes;
  109. }
  110. //////////////////////////////////////////////////////////////////////////////
  111. //
  112. // Loads an RImage with file version 2 into pim from pfile.
  113. //
  114. //////////////////////////////////////////////////////////////////////////////
  115. short RImageFile::LoadVersion2( // Returns SUCCESS on success or FAILURE on
  116. // failure.
  117. RImage* pim, // Image to load into.
  118. RFile* pfile) // File to load from.
  119. {
  120. short sRes = SUCCESS; // Assume success.
  121. // No RFile support for RImage::Type, so we used a U32.
  122. U32 u32Temp = 0;
  123. pfile->Read(&u32Temp);
  124. pim->m_type = (RImage::Type)u32Temp;
  125. pfile->Read(&u32Temp);
  126. pim->m_typeDestination = (RImage::Type)u32Temp;
  127. pfile->Read(&pim->m_ulSize);
  128. // Note that the window ones may need to be read after the other ones or,
  129. // more likely, we may need to put in the same patch that is in version 5.
  130. pfile->Read(&u32Temp);
  131. pim->m_sWinWidth = (short)u32Temp;
  132. pfile->Read(&u32Temp);
  133. pim->m_sWinHeight = (short)u32Temp;
  134. pfile->Read(&u32Temp);
  135. pim->m_sWidth = (short)u32Temp;
  136. pfile->Read(&u32Temp);
  137. pim->m_sHeight = (short)u32Temp;
  138. pfile->Read(&u32Temp);
  139. pim->m_sWinX = (short)u32Temp;
  140. pfile->Read(&u32Temp);
  141. pim->m_sWinY = (short)u32Temp;
  142. pfile->Read(&pim->m_lPitch);
  143. pfile->Read(&pim->m_sDepth);
  144. // If file is still okay . . .
  145. if (pfile->Error() == FALSE)
  146. {
  147. if (pim->CreateData(pim->m_ulSize) == SUCCESS)
  148. {
  149. if (pim->ReadPixelData(pfile) == SUCCESS)
  150. {
  151. ULONG ulPalSize;
  152. if (pfile->Read(&ulPalSize) == 1)
  153. {
  154. if (ulPalSize > 0)
  155. {
  156. pim->CreatePalette();
  157. if (RPalFile::LoadNoVersion(pim->m_pPalette, pfile) != SUCCESS)
  158. {
  159. TRACE("RImageFile::LoadVersion2 - Error loading palette\n");
  160. pim->DestroyPalette();
  161. sRes = FAILURE;
  162. }
  163. }
  164. }
  165. else
  166. {
  167. TRACE("RImageFile::LoadVersion2 - Error checking for palette\n");
  168. sRes = FAILURE;
  169. }
  170. }
  171. else
  172. {
  173. TRACE("RImageFile::LoadVersion2 - Error reading pixel data\n");
  174. pim->DestroyData();
  175. sRes = FAILURE;
  176. }
  177. }
  178. else
  179. {
  180. TRACE("RImageFile::LoadVersion2 - Error: Cannot create memory for "
  181. "pixel data\n");
  182. sRes = FAILURE;
  183. }
  184. }
  185. return sRes;
  186. }
  187. //////////////////////////////////////////////////////////////////////////////
  188. //
  189. // Loads an RImage with file version 3 into pim from pfile.
  190. //
  191. //////////////////////////////////////////////////////////////////////////////
  192. short RImageFile::LoadVersion3( // Returns SUCCESS on success or FAILURE on
  193. // failure.
  194. RImage* /*pim*/, // Image to load into.
  195. RFile* /*pfile*/) // File to load from.
  196. {
  197. short sRes = SUCCESS; // Assume success.
  198. TRACE("LoadVersion3(): No current support for version 3 RImage.\n");
  199. sRes = FAILURE;
  200. return sRes;
  201. }
  202. //////////////////////////////////////////////////////////////////////////////
  203. //
  204. // Loads an RImage with file version 4 into pim from pfile.
  205. //
  206. //////////////////////////////////////////////////////////////////////////////
  207. short RImageFile::LoadVersion4( // Returns SUCCESS on success or FAILURE on failure.
  208. RImage* /*pim*/, // Image to load into.
  209. RFile* /*pfile*/) // File to load from.
  210. {
  211. short sRes = SUCCESS; // Assume success.
  212. TRACE("LoadVersion4(): No current support for version 4 RImage.\n");
  213. sRes = FAILURE;
  214. return sRes;
  215. }
  216. //////////////////////////////////////////////////////////////////////////////
  217. //
  218. // Loads an RImage with file version 5 into pim from pfile.
  219. //
  220. //////////////////////////////////////////////////////////////////////////////
  221. short RImageFile::LoadVersion5( // Returns SUCCESS on success or FAILURE on
  222. // failure.
  223. RImage* pim, // Image to load into.
  224. RFile* pfile) // File to load from.
  225. {
  226. short sRes = SUCCESS; // Assume success.
  227. // No RFile support for RImage::Type, so we used a U32.
  228. U32 u32Temp = 0;
  229. pfile->Read(&u32Temp);
  230. pim->m_type = (RImage::Type)u32Temp;
  231. pfile->Read(&u32Temp);
  232. pim->m_typeDestination = (RImage::Type)u32Temp;
  233. pfile->Read(&pim->m_ulSize);
  234. pfile->Read(&pim->m_sWinWidth);
  235. pfile->Read(&pim->m_sWinHeight);
  236. pfile->Read(&pim->m_sWidth);
  237. pfile->Read(&pim->m_sHeight);
  238. /////////////////////////////////////////////////////////////
  239. // Begin load patch to support older versions of RImage that
  240. // that used sBufferWidth and sBufferHeight in a
  241. // contraversial way.
  242. // Many images, in the days of m_sBufferWidth and
  243. // m_sBufferHeight, saw these vars as representing the width
  244. // and height of the sub buffer within the image defined by
  245. // m_sWidth and m_sHeight. This was incorrect, as Jeff had
  246. // intended these m_sBuffer* to represent the overall size of
  247. // the buffer, and m_sWidth and m_sHeight to represent the
  248. // rectangular sub region. Consequently, these incorrect
  249. // images spread far and wide and even crept into other
  250. // formats, such as SPRY and kludge, seeping their incorrect
  251. // interpretations of the Image.
  252. // Today, images use m_sWidth and m_sHeight to represent the
  253. // entire buffer and new vars (m_sWinWidth & m_sWinHeight)
  254. // to represent the sub "window" inside the buffer. To make
  255. // this work with older formats, the the pair (m_sWidth,
  256. // m_sHeight) is read in before the pair (m_sWinWidth,
  257. // m_sWinHeight). This is intended to make the old
  258. // (m_sBufferWidth, m_sBufferHeight) pair from the files get
  259. // stored in the new (m_sWidth, m_sHeight) pair in memory and
  260. // have the old (m_sWidth, m_sHeight) pair from the files get
  261. // stored in the new (m_sWinWidth, m_sWinHeight). With this
  262. // change the file version would not have to be incremented
  263. // for *.IMG files. The only problem here is that files,
  264. // such as *.SPRY, had their m_sBufferWidth and
  265. // m_sBufferHeight set to 0, incorrectly, as they did not
  266. // understand the proper use of these vars; hence, the patch
  267. // below which detects and fixes this problem.
  268. // To fix the problem, we check for the incorrect condition
  269. // of having the m_sWidth and m_sHeight vars be larger than
  270. // the m_sWinWidth and m_sWinHeight vars. If this is the
  271. // case, we copy the m_sWinWidth and m_sWinHeight into the
  272. // m_sWidth and m_sHeight vars.
  273. /////////////////////////////////////////////////////////////
  274. if (pim->m_sWinWidth > pim->m_sWidth && pim->m_sWinHeight > pim->m_sHeight)
  275. {
  276. pim->m_sWidth = pim->m_sWinWidth;
  277. pim->m_sHeight = pim->m_sWinHeight;
  278. }
  279. /////////////////////////////////////////////////////////////
  280. // End patch to support older versions of RImage.
  281. /////////////////////////////////////////////////////////////
  282. pfile->Read(&pim->m_sWinX);
  283. pfile->Read(&pim->m_sWinY);
  284. pfile->Read(&pim->m_lPitch);
  285. pfile->Read(&pim->m_sDepth);
  286. // If file is still okay . . .
  287. if (pfile->Error() == FALSE)
  288. {
  289. USHORT usFlag;
  290. // See if there is any pixel data to be read
  291. pfile->Read(&usFlag);
  292. if (usFlag == 1)
  293. {
  294. if (pim->CreateData(pim->m_ulSize) == SUCCESS)
  295. {
  296. pim->ReadPixelData(pfile);
  297. }
  298. else
  299. {
  300. TRACE("RImageFile::LoadVersion5 - Error: Cannot allocate memory "
  301. "for pixel data\n");
  302. sRes = FAILURE;
  303. }
  304. }
  305. }
  306. // If file is still okay . . .
  307. if (pfile->Error() == FALSE)
  308. {
  309. USHORT usFlag;
  310. // See if there is a palette to load
  311. pfile->Read(&usFlag);
  312. if (usFlag == 1)
  313. {
  314. pim->CreatePalette();
  315. if (pim->m_pPalette->Load(pfile) != SUCCESS)
  316. {
  317. TRACE("RImageFile::LoadVersion5 - Error loading palette\n");
  318. pim->DestroyPalette();
  319. sRes = FAILURE;
  320. }
  321. }
  322. }
  323. return sRes;
  324. }
  325. //////////////////////////////////////////////////////////////////////////////
  326. // External Functions.
  327. //////////////////////////////////////////////////////////////////////////////
  328. //////////////////////////////////////////////////////////////////////////////
  329. //
  330. // Maps a particular file load onto the appropriate function, if available.
  331. //
  332. //////////////////////////////////////////////////////////////////////////////
  333. short RImageFile::Load( // Returns SUCCESS on success or FAILURE on failure.
  334. RImage* pim, // Image to load into.
  335. RFile* pfile) // File to load from.
  336. {
  337. short sRes = SUCCESS; // Assume success.
  338. // Get finger print . . .
  339. ULONG ulFinger;
  340. if (pfile->Read(&ulFinger) == 1)
  341. {
  342. if (ulFinger == IMAGE_COOKIE)
  343. {
  344. ULONG ulVersion;
  345. if (pfile->Read(&ulVersion) == 1)
  346. {
  347. switch (ulVersion)
  348. {
  349. #if defined(IMAGE_LOAD_1) || defined(IMAGE_LOAD_ALL)
  350. case 1:
  351. sRes = LoadVersion1(pim, pfile);
  352. break;
  353. #endif // IMAGE_LOAD_1
  354. #if defined(IMAGE_LOAD_2) || defined(IMAGE_LOAD_ALL)
  355. case 2:
  356. sRes = LoadVersion2(pim, pfile);
  357. break;
  358. #endif // IMAGE_LOAD_2
  359. #if defined(IMAGE_LOAD_3) || defined(IMAGE_LOAD_ALL)
  360. case 3:
  361. sRes = LoadVersion3(pim, pfile);
  362. break;
  363. #endif // IMAGE_LOAD_3
  364. #if defined(IMAGE_LOAD_4) || defined(IMAGE_LOAD_ALL)
  365. case 4:
  366. sRes = LoadVersion4(pim, pfile);
  367. break;
  368. #endif // IMAGE_LOAD_4
  369. // #if defined(IMAGE_LOAD_5) || defined(IMAGE_LOAD_ALL)
  370. case 5:
  371. sRes = LoadVersion5(pim, pfile);
  372. break;
  373. // #endif // IMAGE_LOAD_5
  374. default: // No current support.
  375. TRACE("RImage::Load - Error: Unsupported version.\n");
  376. TRACE("RImage::Load - Current RImage version %d\n", IMAGE_CURRENT_VERSION);
  377. TRACE("RImage::Load - This file's version %lu\n", ulVersion);
  378. TRACE("RImage::Load - See ImageFile.cpp for details on "
  379. "supporting older RImage formats.\n");
  380. sRes = FAILURE;
  381. break;
  382. }
  383. // If no errors . . .
  384. if (sRes == SUCCESS && !pfile->Error())
  385. {
  386. // Call the special load function for this type if any
  387. LOADFUNC clf = GETLOADFUNC(pim->m_type);
  388. if (clf != NULL)
  389. sRes = (*clf)(pim, pfile/*, ulVersion*/);
  390. }
  391. }
  392. else
  393. {
  394. TRACE("RImage::Load - Error reading file version\n");
  395. sRes = FAILURE;
  396. }
  397. }
  398. else
  399. {
  400. // If it matches the BMP cookie . . .
  401. if ((ulFinger & 0x0000FFFF) == BMP_COOKIE)
  402. {
  403. // Seek back for LoadDib() call. 99% of the time this will not cause a seek
  404. // b/c it's within the buffered i/o's buffer.
  405. // The other 1%.....uhhh...well.
  406. pfile->Seek( - (long)sizeof(ulFinger), SEEK_CUR);
  407. // Invoke LoadDib() . . .
  408. sRes = pim->LoadDib(pfile);
  409. }
  410. else
  411. {
  412. TRACE("RImage::Load - Error: Wrong filetype, Image files should start with 'IM ' and "
  413. "DIB files should start with 'BM'.\n");
  414. sRes = FAILURE;
  415. }
  416. }
  417. }
  418. else
  419. {
  420. TRACE("ImageLoad(): Error reading RImage format finger print.\n");
  421. sRes = FAILURE;
  422. }
  423. return sRes;
  424. }
  425. ///////////////////////////////////////////////////////////////////////////////
  426. // EOF
  427. ///////////////////////////////////////////////////////////////////////////////