laymage.cpp 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593
  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. // LAYMAGE.CPP
  21. //
  22. // Created on 10/04/96 BRH
  23. // Implemented 10/04/96 BRH
  24. //
  25. // 10/04/96 BRH Started this class for use in several utilities
  26. // dealing with multiple layer Photoshop images.
  27. // This class loads a Photoshop file and creates
  28. // a CImage for each layer and provides way of
  29. // accessing specific layers.
  30. //
  31. // 10/10/96 BRH Put in basic support which includes loading a
  32. // layered Photoshop file and converting it to
  33. // a CLaymage in memory. GetLayer functions provide
  34. // access to the layers either by name or number,
  35. // and GetLayerName will give the names of a
  36. // specific layer number.
  37. //
  38. // 10/11/96 BRH Added SetPSD function which instead of loading
  39. // all of the layers as LoadPSD does, just reads in
  40. // the layer names, and saves file positions for
  41. // the layers header section and layers channel
  42. // data section. Then GetLayer is called, if the
  43. // layers are all in memory because of LoadPSD,
  44. // then it will return the pointer to that CImage
  45. // layer. If SetPSD was called, then it will read
  46. // from the Photoshop, the requested layer and
  47. // create the CImage. Once the user is done with
  48. // a layer, they can call FreeLayer() with the layer
  49. // name or number and it will free that CImage.
  50. // These features were added to avoid problems with
  51. // large Photoshop images which expanded to fill all
  52. // available RAM.
  53. //
  54. // 10/22/96 JMI Moved #include <stdlib.h> and #include <string.h> to
  55. // before #include "System.h".
  56. //
  57. // 10/28/96 MJR Minor tweaks to make it compile correctly and with
  58. // warnings under CodeWarrior. No functional changes.
  59. //
  60. // 11/01/96 BRH Changed CLaymage to RLaymage to conform to new
  61. // RSPiX class names.
  62. //
  63. // 11/01/96 JMI Changed:
  64. // Old label: New label:
  65. // ========= =========
  66. // ENDIAN_BIG RFile::BigEndian
  67. // ENDIAN_LITTLE RFile::LittleEndian
  68. //
  69. // Also, changed all members referenced in RImage to
  70. // m_ and all position/dimension members referenced in
  71. // RImage to type short usage.
  72. //
  73. // 02/13/97 MJR Added Reset() to reset object back to its initial
  74. // freshly-constructed state.
  75. //
  76. // Fixed a problem having to do with single-layer
  77. // files. The code was assuming that the layer-related
  78. // section always exists, but it doesn't for files with
  79. // just one layer.
  80. //
  81. // 02/27/97 BRH Fixed bug in ReadLayerInfo where the channel IDs
  82. // were being read into only the last Channel ID,
  83. // causing many channels to be skipped. Also
  84. // ConvertToImage now initializes the image data buffer
  85. // to white pixels that are transparent (in Photoshop
  86. // fashion) to match Photoshop layers that may contain
  87. // a rectangular area that is smaller than the full
  88. // image size.
  89. //
  90. //////////////////////////////////////////////////////////////////////
  91. #include <stdlib.h>
  92. #include <string.h>
  93. #include "System.h"
  94. #ifdef PATHS_IN_INCLUDES
  95. #include "GREEN/Image/Image.h"
  96. #include "ORANGE/File/file.h"
  97. #include "ORANGE/Laymage/laymage.h"
  98. #include "BLUE/Blue.h"
  99. #else
  100. #include "Image.h"
  101. #include "FILE.H"
  102. #include "LAYMAGE.H"
  103. #include "Blue.h"
  104. #endif // PATHS_IN_INCLUDES
  105. //////////////////////////////////////////////////////////////////////
  106. //
  107. // Constructor
  108. //
  109. // Description:
  110. // General constructor for RLaymage for initializing member variables
  111. //
  112. // Parameters:
  113. // none
  114. //
  115. // Returns:
  116. // none
  117. //
  118. //////////////////////////////////////////////////////////////////////
  119. RLaymage::RLaymage()
  120. {
  121. short i;
  122. for (i = 0; i < LAYMAGE_MAXCHANNELS; i++)
  123. m_pcChannels[i] = NULL;
  124. m_sNumLayers = 0;
  125. m_apImages = NULL;
  126. m_apszLayerNames = NULL;
  127. m_lTellLayers = 0;
  128. m_lTellChannels = 0;
  129. }
  130. //////////////////////////////////////////////////////////////////////
  131. //
  132. // Destructor
  133. //
  134. // Description:
  135. // Deallocates memory for RImage layers and layer names
  136. //
  137. // Parameters:
  138. // none
  139. //
  140. // Returns:
  141. // none
  142. //
  143. //////////////////////////////////////////////////////////////////////
  144. RLaymage::~RLaymage()
  145. {
  146. Reset();
  147. }
  148. //////////////////////////////////////////////////////////////////////
  149. //
  150. // Reset
  151. //
  152. // Description:
  153. // Resets object back to its freshly-constructed state
  154. //
  155. // Parameters:
  156. // none
  157. //
  158. // Returns:
  159. // none
  160. //
  161. //////////////////////////////////////////////////////////////////////
  162. void RLaymage::Reset()
  163. {
  164. ClearChannelBuffers();
  165. FreeAllLayers();
  166. FreeLayerArrays();
  167. m_sNumLayers = 0;
  168. m_apImages = NULL;
  169. m_apszLayerNames = NULL;
  170. m_lTellLayers = 0;
  171. m_lTellChannels = 0;
  172. }
  173. //////////////////////////////////////////////////////////////////////
  174. //
  175. // ClearChannelBuffers
  176. //
  177. // Description:
  178. // Deallocate all channel buffers and reset the pointers
  179. //
  180. // Parameters:
  181. // none
  182. //
  183. // Returns:
  184. // none
  185. //
  186. //////////////////////////////////////////////////////////////////////
  187. void RLaymage::ClearChannelBuffers(void)
  188. {
  189. short i;
  190. for (i = 0; i < LAYMAGE_MAXCHANNELS; i++)
  191. if (m_pcChannels[i])
  192. {
  193. free(m_pcChannels[i]);
  194. m_pcChannels[i] = NULL;
  195. }
  196. }
  197. //////////////////////////////////////////////////////////////////////
  198. //
  199. // AllocateChannelBuffers
  200. //
  201. // Description:
  202. // Allocate the 4 standard channel buffers, Red, Green, Blue, and
  203. // Alpha.
  204. //
  205. // Parameters:
  206. // Number of bytes to be allocated for each buffer
  207. //
  208. // Returns:
  209. // SUCCESS if all buffers were allocated
  210. // FAILURE if memory was not allocated for the buffers
  211. //
  212. //////////////////////////////////////////////////////////////////////
  213. short RLaymage::AllocateChannelBuffers(ULONG ulSize)
  214. {
  215. short sReturn = SUCCESS;
  216. ClearChannelBuffers();
  217. m_pcChannels[LAYMAGE_RED] = (char*) calloc(ulSize, 1);
  218. m_pcChannels[LAYMAGE_GREEN] = (char*) calloc(ulSize, 1);
  219. m_pcChannels[LAYMAGE_BLUE] = (char*) calloc(ulSize, 1);
  220. m_pcChannels[LAYMAGE_ALPHA] = (char*) calloc(ulSize, 1);
  221. if (m_pcChannels[LAYMAGE_RED] &&
  222. m_pcChannels[LAYMAGE_GREEN] &&
  223. m_pcChannels[LAYMAGE_BLUE] &&
  224. m_pcChannels[LAYMAGE_ALPHA])
  225. sReturn = SUCCESS;
  226. else
  227. {
  228. sReturn = FAILURE;
  229. ClearChannelBuffers();
  230. }
  231. return sReturn;
  232. }
  233. //////////////////////////////////////////////////////////////////////
  234. //
  235. // SetPSD
  236. //
  237. // Description:
  238. // Opens the given Photoshop file and reads it layer names and
  239. // saves poistions to key points in the Photoshop file. It
  240. // does not load any layers. When the user requests a layer
  241. // using GetLayer(), it will load that layer from this Photoshop
  242. // file.
  243. //
  244. // Parameters:
  245. // pszFilename = filename of Photoshop file (.PSD) to be set
  246. //
  247. // Returns:
  248. // SUCCESS if the file was loaded and set up
  249. // FAILURE otherwise - TRACE information gives failure
  250. //
  251. //////////////////////////////////////////////////////////////////////
  252. short RLaymage::SetPSD(char* pszFilename)
  253. {
  254. RFile cf;
  255. RFile cfChannel;
  256. short sReturn = SUCCESS;
  257. short i;
  258. strcpy(m_szPhotoshopFilename, pszFilename);
  259. if (ReadPSDHeader(pszFilename) != SUCCESS)
  260. {
  261. TRACE("RLaymage::SetPSD - Failed - header could not be read\n");
  262. goto error;
  263. }
  264. if (cf.Open(pszFilename, "rb", RFile::BigEndian) != SUCCESS)
  265. {
  266. TRACE("RLaymage::SetPSD - Error cannot open file %s\n", pszFilename);
  267. goto error;
  268. }
  269. if (cfChannel.Open(pszFilename, "rb", RFile::BigEndian) != SUCCESS)
  270. {
  271. TRACE("RLaymage::SetPSD - Error cannot open channel file %s\n", pszFilename);
  272. goto error;
  273. }
  274. cf.Seek(m_lTellLayers, SEEK_SET);
  275. cfChannel.Seek(m_lTellChannels, SEEK_SET);
  276. i = 0;
  277. while (i < m_sNumLayers)
  278. ReadLayerName(i++, &cf);
  279. cf.Close();
  280. cfChannel.Close();
  281. return SUCCESS;
  282. error:
  283. cf.Close();
  284. cfChannel.Close();
  285. return FAILURE;
  286. }
  287. //////////////////////////////////////////////////////////////////////
  288. //
  289. // LoadPSD
  290. //
  291. // Description:
  292. // Load the given Photoshop file and convert its layers into a
  293. // series of RImages.
  294. //
  295. // Parameters:
  296. // pszFilename = filename of Photoshop file (.PSD) to be loaded
  297. //
  298. // Returns:
  299. // SUCCESS if the file was loaded and converted
  300. //
  301. //////////////////////////////////////////////////////////////////////
  302. short RLaymage::LoadPSD(char* pszFilename)
  303. {
  304. RFile cf;
  305. RFile cfChannel;
  306. short sReturn = SUCCESS;
  307. short i;
  308. strcpy(m_szPhotoshopFilename, pszFilename);
  309. if (ReadPSDHeader(pszFilename) != SUCCESS)
  310. {
  311. TRACE("RLaymage::LoadPSD - Failed - header could not be read\n");
  312. goto error;
  313. }
  314. if (cf.Open(pszFilename, "rb", RFile::BigEndian) != SUCCESS)
  315. {
  316. TRACE("RLaymage::LoadPSD - Error cannot open file %s\n", pszFilename);
  317. goto error;
  318. }
  319. if (cfChannel.Open(pszFilename, "rb", RFile::BigEndian) != SUCCESS)
  320. {
  321. TRACE("RLaymage::LoadPSD - Error cannot open channel file %s\n", pszFilename);
  322. goto error;
  323. }
  324. cf.Seek(m_lTellLayers, SEEK_SET);
  325. cfChannel.Seek(m_lTellChannels, SEEK_SET);
  326. i = 0;
  327. while (i < m_sNumLayers)
  328. ReadLayerInfo(i++, &cf, &cfChannel);
  329. cf.Close();
  330. cfChannel.Close();
  331. return SUCCESS;
  332. error:
  333. cf.Close();
  334. cfChannel.Close();
  335. return FAILURE;
  336. }
  337. //////////////////////////////////////////////////////////////////////
  338. //
  339. // ReadPSDHeader
  340. //
  341. // Description:
  342. // Reads in the header for the Photoshop file and sets the
  343. // width, height, number of layers and the file positions to
  344. // the beginning of the layers header information, and the
  345. // beginning of the channel data. This routine can be called
  346. // from either LoadPSD or SetPSD to get this information. SetPSD
  347. // will then just read the names of the layers, and LoadPSD
  348. // will call the ReadLayerInfo for each layer.
  349. //
  350. // Parameters:
  351. // pszFilename = name of the Photoshop header to read
  352. //
  353. // Returns:
  354. // SUCCESS if the file was opened and header was read successfully
  355. // FAILURE if there was an error - TRACE messages will help
  356. // pinpoint the error.
  357. //
  358. //////////////////////////////////////////////////////////////////////
  359. short RLaymage::ReadPSDHeader(char* pszFilename)
  360. {
  361. RFile cf;
  362. RFile cfChannel;
  363. short sReturn = SUCCESS;
  364. ULONG ulData;
  365. USHORT usData;
  366. if (cf.Open(pszFilename, "rb", RFile::BigEndian) != SUCCESS)
  367. {
  368. TRACE("RLaymage::ReadPSDHeader - Error cannot open file %s\n", pszFilename);
  369. goto error;
  370. }
  371. if (cfChannel.Open(pszFilename, "rb", RFile::BigEndian) != SUCCESS)
  372. {
  373. TRACE("RLaymage::ReadPSDHeader - Error cannot open channel file %s\n", pszFilename);
  374. goto error;
  375. }
  376. //-----------------------------------------------------------------
  377. // Read in Photoshop header
  378. //-----------------------------------------------------------------
  379. // Read file signature to make sure it is a Photoshop file
  380. cf.Read(&ulData);
  381. if (ulData != LAYMAGE_PHOTOSHOP_SIGNATURE)
  382. {
  383. TRACE("RLaymage::ReadPSDHeader - Error - File signature is not 8BPS\n");
  384. goto error;
  385. }
  386. // Read version number and make sure it matches
  387. cf.Read(&usData);
  388. if (usData != 1)
  389. {
  390. TRACE("RLaymage::ReadPSDHeader - Error - File version is not 1\n");
  391. goto error;
  392. }
  393. // Skip over reserved space
  394. cf.Seek(6, SEEK_CUR);
  395. // Read number of channels
  396. cf.Read(&m_sSpecialNumChannels);
  397. // Read image size
  398. cf.Read(&m_lHeight);
  399. cf.Read(&m_lWidth);
  400. // Skip Depth of channels field
  401. cf.Seek(2, SEEK_CUR);
  402. // Read mode and make sure it is RGB
  403. cf.Read(&usData);
  404. if (usData != 3)
  405. {
  406. TRACE("RLaymage::ReadPSDHeader - Error - file not in RGB color mode\n");
  407. goto error;
  408. }
  409. // Read the size of the color mode data section and skip it
  410. cf.Read(&ulData);
  411. cf.Seek(ulData, SEEK_CUR);
  412. // Read the size of the image resource section and skip it
  413. cf.Read(&ulData);
  414. cf.Seek(ulData, SEEK_CUR);
  415. // Read the size of the misc info section. If the section exists,
  416. // then the image probably has more than one layer. If it doesn't,
  417. // then the image has just one layer.
  418. cf.Read(&ulData);
  419. if (ulData > 0)
  420. {
  421. // This file has layer info
  422. m_sHasLayerInfo = 1;
  423. // Read the size of the layers section
  424. cf.Read(&ulData);
  425. // Get the number of layers (if negative, get absolute value)
  426. cf.Read(&m_sNumLayers);
  427. if (m_sNumLayers < 0)
  428. m_sNumLayers = -m_sNumLayers;
  429. // Read through the Layer info once to find the end of the
  430. // headers and the beginning of the channel data.
  431. cfChannel.Seek(cf.Tell(), SEEK_SET);
  432. SetChannelPointer(m_sNumLayers, &cfChannel);
  433. }
  434. else
  435. {
  436. // This file has no layer info
  437. m_sHasLayerInfo = 0;
  438. // There's only one layer
  439. m_sNumLayers = 1;
  440. // The misc info section is empty, and what follows is basically
  441. // the channel data for the one and only layer.
  442. cfChannel.Seek(cf.Tell(), SEEK_SET);
  443. }
  444. m_lTellLayers = cf.Tell();
  445. m_lTellChannels = cfChannel.Tell();
  446. // Allocate RImage and name arrays for each layer
  447. if (AllocateLayerArrays(m_sNumLayers) != SUCCESS)
  448. {
  449. TRACE("RLaymage::ReadPSDHeader - Error allocating layer arrays\n");
  450. goto error;
  451. }
  452. cf.Close();
  453. cfChannel.Close();
  454. return SUCCESS;
  455. error:
  456. cf.Close();
  457. cfChannel.Close();
  458. return FAILURE;
  459. }
  460. //////////////////////////////////////////////////////////////////////
  461. //
  462. // ReadLayer
  463. //
  464. // Description:
  465. // This function is called by GetLayer when the layer requested
  466. // is not currently loaded into memory and needs to be retrieved
  467. // from the Photoshop file. It interfaces with ReadLayerInfo
  468. // by opening the Layer and Channel files and setting them to the
  469. // saved locations. Then it loops through the layers, reading each
  470. // one in order to parse the file. If the layer it just read
  471. // in the loop was not the requested layer, then it frees that
  472. // layer and reads the next one until it finds the one it wants.
  473. //
  474. // Parameters
  475. // sRequestedLayer = The number of the layer to be set in memory
  476. //
  477. // Returns:
  478. // SUCCESS if the layer was found and read
  479. // FAILURE if there was an error
  480. //
  481. //////////////////////////////////////////////////////////////////////
  482. short RLaymage::ReadLayer(short sRequestedLayer)
  483. {
  484. RFile cf;
  485. RFile cfChannel;
  486. short sReturn = SUCCESS;
  487. short i;
  488. if (cf.Open(m_szPhotoshopFilename, "rb", RFile::BigEndian) != SUCCESS)
  489. {
  490. TRACE("RLaymage::ReadLayer - Error cannot open file %s\n", m_szPhotoshopFilename);
  491. goto error;
  492. }
  493. if (cfChannel.Open(m_szPhotoshopFilename, "rb", RFile::BigEndian) != SUCCESS)
  494. {
  495. TRACE("RLaymage::ReadPSDHeader - Error cannot open channel file %s\n", m_szPhotoshopFilename);
  496. goto error;
  497. }
  498. cf.Seek(m_lTellLayers, SEEK_SET);
  499. cfChannel.Seek(m_lTellChannels, SEEK_SET);
  500. i = 0;
  501. while (i < sRequestedLayer)
  502. {
  503. if (ReadLayerInfo(i, &cf, &cfChannel) != SUCCESS)
  504. goto error;
  505. FreeLayer(i);
  506. i++;
  507. }
  508. if (i == sRequestedLayer)
  509. if (ReadLayerInfo(i, &cf, &cfChannel) != SUCCESS)
  510. goto error;
  511. cf.Close();
  512. cfChannel.Close();
  513. return SUCCESS;
  514. error:
  515. cf.Close();
  516. cfChannel.Close();
  517. return FAILURE;
  518. }
  519. //////////////////////////////////////////////////////////////////////
  520. //
  521. // SetChannelPointer
  522. //
  523. // Description:
  524. // Private function to set a second file pointer to the
  525. // beginning of the Channel data so that two pointers
  526. // working together can read both the layer header information
  527. // and the data. This routine gets an open RFile pointer
  528. // at the start of the layer header information and it will
  529. // skip through the header information for all of the layers
  530. // and will be left at the beginning of the channel data for
  531. // the first layer.
  532. //
  533. // Parameters:
  534. // sNumLayers = number of layers to be skipped
  535. // pcfChannel = RFile pointer to open Photoshop file at
  536. // the beginning of the Layers header section
  537. // which will be moved to the beginning of the
  538. // channel data for the layers.
  539. //
  540. // Returns:
  541. // SUCCESS if the pointer was skipped successfully
  542. // FAILURE otherwise
  543. //
  544. //////////////////////////////////////////////////////////////////////
  545. short RLaymage::SetChannelPointer(short sNumLayers, RFile* pcfChannel)
  546. {
  547. ULONG ulData;
  548. USHORT usNumChannels = 0;
  549. USHORT i;
  550. UCHAR ucData;
  551. short sReturn = FAILURE;
  552. short sLayer;
  553. if (pcfChannel && pcfChannel->IsOpen())
  554. {
  555. pcfChannel->ClearError();
  556. for (sLayer = 0; sLayer < sNumLayers; sLayer++)
  557. {
  558. // Skip over 4 longs of layer bounding rectangle
  559. pcfChannel->Seek(16, SEEK_CUR);
  560. pcfChannel->Read(&usNumChannels);
  561. // For each channel skip over chennel ID and length of data
  562. for (i = 0; i < usNumChannels; i++)
  563. pcfChannel->Seek(6, SEEK_CUR);
  564. // Skip over blend mode signature, blend info, opacity, clip,
  565. // flags, and extra data size
  566. pcfChannel->Seek(16, SEEK_CUR);
  567. // Get size of layer mask data and skip over it
  568. pcfChannel->Read(&ulData);
  569. pcfChannel->Seek(ulData, SEEK_CUR);
  570. // Get size of blending ranges and skip over it
  571. pcfChannel->Read(&ulData);
  572. pcfChannel->Seek(ulData, SEEK_CUR);
  573. // Get the pascal formatted layer name string
  574. // and skip over it
  575. pcfChannel->Read(&ucData);
  576. char* pszName = (char*) malloc(ucData);
  577. pcfChannel->Read(pszName, ucData);
  578. free (pszName);
  579. // The name should be padded to a multiple of 4 bytes
  580. // so skip the pad bytes if any.
  581. if ((ucData+1) % 4)
  582. pcfChannel->Seek((4-((ucData+1) % 4)), SEEK_CUR);
  583. }
  584. if (!pcfChannel->Error())
  585. sReturn = SUCCESS;
  586. }
  587. return sReturn;
  588. }
  589. //////////////////////////////////////////////////////////////////////
  590. //
  591. // ReadLayerInfo
  592. //
  593. // Description:
  594. // This is called for each layer. It creates a new RImage
  595. // layer, reads the Photoshop data for the layer, and
  596. // converts it to a 32-bit ARGB format RImage
  597. //
  598. // Parameters:
  599. // sLayerNum = current layer number
  600. // pcfLayer = pointer to layer header portion of file
  601. // pcfChannel = pointer to channel data portion of file
  602. //
  603. // Returns:
  604. // SUCCESS if layer was loaded and converted successfully
  605. // FAILURE otherwise
  606. //
  607. //////////////////////////////////////////////////////////////////////
  608. short RLaymage::ReadLayerInfo(short sLayerNum, RFile* pcfLayer,
  609. RFile* pcfChannel)
  610. {
  611. ULONG ulData;
  612. USHORT usData;
  613. UCHAR ucData;
  614. short asChannelID[LAYMAGE_MAXCHANNELS];
  615. USHORT usNextChannel = 0;
  616. USHORT usNumChannels = 0;
  617. ULONG ulTop;
  618. ULONG ulBottom;
  619. ULONG ulLeft;
  620. ULONG ulRight;
  621. USHORT k;
  622. USHORT i;
  623. short sReturn = SUCCESS;
  624. pcfLayer->ClearError();
  625. pcfChannel->ClearError();
  626. if (m_sHasLayerInfo)
  627. {
  628. // Read the bounding rectangle for this layer
  629. pcfLayer->Read(&ulTop);
  630. pcfLayer->Read(&ulLeft);
  631. pcfLayer->Read(&ulBottom);
  632. pcfLayer->Read(&ulRight);
  633. // Read number of channels
  634. pcfLayer->Read(&usNumChannels);
  635. // Get channel ID's (and skip channel sizes)
  636. for (i = 0; i < usNumChannels; i++)
  637. {
  638. pcfLayer->Read(&asChannelID[i]);
  639. pcfLayer->Read(&ulData);
  640. }
  641. // Skip blend mode signature, blend info, opacity, clip, flags and extra data size
  642. pcfLayer->Seek(16, SEEK_CUR);
  643. // Get size of layer mask data and skip over it
  644. pcfLayer->Read(&ulData);
  645. pcfLayer->Seek(ulData, SEEK_CUR);
  646. // Get size of layer blending ranges and skip over it
  647. pcfLayer->Read(&ulData);
  648. pcfLayer->Seek(ulData, SEEK_CUR);
  649. // Get the pascal formatted layer name string
  650. // Get the length of the string
  651. pcfLayer->Read(&ucData);
  652. // If the layer name has already been read, seek over it and
  653. // leave the string alone.
  654. if (m_apszLayerNames[sLayerNum])
  655. pcfLayer->Seek(ucData, SEEK_CUR);
  656. else
  657. {
  658. m_apszLayerNames[sLayerNum] = new char[ucData+1];
  659. pcfLayer->Read(m_apszLayerNames[sLayerNum], ucData);
  660. m_apszLayerNames[sLayerNum][ucData] = 0;
  661. }
  662. // Skip to multiple of 4 following string
  663. if ((ucData+1) % 4)
  664. pcfLayer->Seek((4 - (ucData+1) % 4), SEEK_CUR);
  665. // Allocate 4 channel buffers for Alpha, R, G, and B channels
  666. if (AllocateChannelBuffers((ulBottom-ulTop)*(ulRight-ulLeft)) == SUCCESS)
  667. {
  668. // Read the channel data into buffers
  669. short sChannelSel;
  670. for (k = 0; k < usNumChannels; k++)
  671. {
  672. // If the channel is Alpha or R G or B, read the data
  673. if (asChannelID[k] > -2 && asChannelID[k] < 3)
  674. {
  675. switch (asChannelID[k])
  676. {
  677. case -1:
  678. sChannelSel = LAYMAGE_ALPHA;
  679. break;
  680. case 0:
  681. sChannelSel = LAYMAGE_RED;
  682. break;
  683. case 1:
  684. sChannelSel = LAYMAGE_GREEN;
  685. break;
  686. case 2:
  687. sChannelSel = LAYMAGE_BLUE;
  688. break;
  689. default:
  690. sChannelSel = LAYMAGE_IGNORE;
  691. break;
  692. }
  693. // Read compression type
  694. pcfChannel->Read(&usData);
  695. if (usData == 0)
  696. {
  697. // Read RAW uncompressed data
  698. if (!m_pcChannels[sChannelSel])
  699. TRACE("RLaymage::ReadLayerInfo - Error allocating memory for channel buffer\n");
  700. else
  701. pcfChannel->Read(m_pcChannels[sChannelSel], (ulBottom-ulTop)*(ulRight-ulLeft));
  702. }
  703. else
  704. {
  705. // Read RLE compressed data
  706. USHORT m;
  707. ULONG ulCompSize = 0;
  708. for (m = 0; m < ulBottom-ulTop; m++)
  709. {
  710. pcfChannel->Read(&usData);
  711. ulCompSize += usData;
  712. }
  713. if (!m_pcChannels[sChannelSel])
  714. TRACE("RLaymage::ReadLayerInfo - Error allocating memory for channel buffer\n");
  715. else
  716. RLE_Decompress(m_pcChannels[sChannelSel], ulCompSize, pcfChannel);
  717. }
  718. }
  719. else
  720. {
  721. // discard the channel
  722. // Read compression type
  723. pcfChannel->Read(&usData);
  724. if (usData == 0)
  725. {
  726. // If uncompressed, skip the size of the image given by
  727. // the bounding rectangle
  728. pcfChannel->Seek((ulBottom-ulTop)*(ulRight-ulLeft), SEEK_CUR);
  729. }
  730. else
  731. {
  732. // If compressed, the length of each line is stored at
  733. // this position in the file. Get the total size of
  734. // compressed data and then skip over it.
  735. USHORT j;
  736. ULONG ulSkip = 0;
  737. for (j = 0; j < ulBottom - ulTop; j++)
  738. {
  739. pcfChannel->Read(&usData);
  740. ulSkip += usData;
  741. }
  742. pcfChannel->Seek(ulSkip, SEEK_CUR);
  743. }
  744. }
  745. }
  746. // Convert color planes into a 32-bit ARGB RImage
  747. ConvertToImage(sLayerNum, ulTop, ulBottom, ulLeft, ulRight);
  748. }
  749. else
  750. {
  751. sReturn = FAILURE;
  752. TRACE("RLaymage::ReadLayerInfo - Error allocating channel buffers\n");
  753. }
  754. }
  755. else
  756. {
  757. // If the layer name hasn't been set, set it to "background" to match the photoshop default name
  758. if (m_apszLayerNames[sLayerNum] == 0)
  759. {
  760. m_apszLayerNames[sLayerNum] = new char[20+1];
  761. strcpy(m_apszLayerNames[sLayerNum], "background");
  762. }
  763. // Allocate 4 channel buffers for Alpha, R, G, and B channels
  764. if (AllocateChannelBuffers(m_lWidth * m_lHeight) == SUCCESS)
  765. {
  766. // Read compression type
  767. USHORT usComp;
  768. pcfChannel->Read(&usComp);
  769. // Read the channel data into buffers. The order of the channels seems to be fixed in this
  770. // type of file: RED, GREEN, BLUE, followed by any user-defined channels, and we assume the
  771. // first one after BLUE is ALPHA.
  772. if (usComp == 0)
  773. {
  774. // Read RAW uncompressed data for each channel
  775. pcfChannel->Read(m_pcChannels[LAYMAGE_RED], m_lWidth * m_lHeight);
  776. pcfChannel->Read(m_pcChannels[LAYMAGE_GREEN], m_lWidth * m_lHeight);
  777. pcfChannel->Read(m_pcChannels[LAYMAGE_BLUE], m_lWidth * m_lHeight);
  778. pcfChannel->Read(m_pcChannels[LAYMAGE_ALPHA], m_lWidth * m_lHeight);
  779. }
  780. else
  781. {
  782. // Read RLE compressed data. This starts with a byte count for every row of every
  783. // channel (in other words, there are row * channel number of byte counts) followed
  784. // by the compressed data for all the rows. Our compression is oriented towards
  785. // doing each channel separately, so we have to jump around in the file alot.
  786. ULONG ulCompSize[4] = { 0, 0, 0, 0 };
  787. for (k = 0; k < 4; k++)
  788. {
  789. for (USHORT m = 0; m < m_lHeight; m++)
  790. {
  791. pcfChannel->Read(&usData);
  792. ulCompSize[k] += usData;
  793. }
  794. }
  795. RLE_Decompress(m_pcChannels[LAYMAGE_RED], ulCompSize[0], pcfChannel);
  796. RLE_Decompress(m_pcChannels[LAYMAGE_GREEN], ulCompSize[1], pcfChannel);
  797. RLE_Decompress(m_pcChannels[LAYMAGE_BLUE], ulCompSize[2], pcfChannel);
  798. RLE_Decompress(m_pcChannels[LAYMAGE_ALPHA], ulCompSize[3], pcfChannel);
  799. }
  800. // Convert color planes into a 32-bit ARGB RImage
  801. ConvertToImage(sLayerNum, 0, m_lHeight, 0, m_lWidth);
  802. }
  803. else
  804. {
  805. sReturn = FAILURE;
  806. TRACE("RLaymage::ReadLayerInfo - Error allocating channel buffers\n");
  807. }
  808. }
  809. ClearChannelBuffers();
  810. return sReturn;
  811. }
  812. //////////////////////////////////////////////////////////////////////
  813. //
  814. // ReadLayerName
  815. //
  816. // Description:
  817. // Read the name of the given layer. This will be called in
  818. // a loop much like ReadLayerInfo, but it only gets the names,
  819. // it does not read the channel data.
  820. //
  821. // Parameters:
  822. // sLayer = layer number to read
  823. // pcfLayer = pointer to open RFile at layer header
  824. //
  825. // Returns:
  826. // SUCCESS if read successfully
  827. // FAILURE if there was an error
  828. //
  829. //////////////////////////////////////////////////////////////////////
  830. short RLaymage::ReadLayerName(short sLayerNum, RFile* pcfLayer)
  831. {
  832. ULONG ulData;
  833. USHORT usData;
  834. UCHAR ucData;
  835. ULONG* pulChannelLength = NULL;
  836. short* psChannelID = NULL;
  837. USHORT usNextChannel = 0;
  838. USHORT usNumChannels = 0;
  839. ULONG ulTop;
  840. ULONG ulBottom;
  841. ULONG ulLeft;
  842. ULONG ulRight;
  843. USHORT i;
  844. short sReturn = SUCCESS;
  845. pcfLayer->ClearError();
  846. // Read the bounding rectangle for this layer
  847. pcfLayer->Read(&ulTop);
  848. pcfLayer->Read(&ulLeft);
  849. pcfLayer->Read(&ulBottom);
  850. pcfLayer->Read(&ulRight);
  851. pcfLayer->Read(&usNumChannels);
  852. pulChannelLength = (ULONG*) calloc(usNumChannels, sizeof(ULONG));
  853. psChannelID = (short*) calloc(usNumChannels, sizeof(short));
  854. if (pulChannelLength == NULL || psChannelID == NULL)
  855. {
  856. TRACE("RLaymage::ReadLayerInfo - Error allocating buffers for channel data\n");
  857. sReturn = FAILURE;
  858. }
  859. for (i = 0; i < usNumChannels; i++)
  860. {
  861. // Get channel ID
  862. pcfLayer->Read(&usData);
  863. psChannelID[i] = usData;
  864. pcfLayer->Read(&ulData);
  865. pulChannelLength[usNextChannel++] = ulData;
  866. }
  867. // Read the blend mode signature which is always 8BIM
  868. pcfLayer->Read(&ulData);
  869. // Skip Blend info, opacity, clip, flags and extra data size
  870. pcfLayer->Seek(12, SEEK_CUR);
  871. // Get size of layer mask data and skip over it
  872. pcfLayer->Read(&ulData);
  873. pcfLayer->Seek(ulData, SEEK_CUR);
  874. // Get size of layer blending ranges and skip over it
  875. pcfLayer->Read(&ulData);
  876. pcfLayer->Seek(ulData, SEEK_CUR);
  877. // Get the pascal formatted layer name string
  878. // Get the length of the string
  879. pcfLayer->Read(&ucData);
  880. m_apszLayerNames[sLayerNum] = new char[ucData+1];
  881. pcfLayer->Read(m_apszLayerNames[sLayerNum], ucData);
  882. m_apszLayerNames[sLayerNum][ucData] = 0;
  883. // Skip to multiple of 4 following string
  884. if ((ucData+1) % 4)
  885. pcfLayer->Seek((4 - (ucData+1) % 4), SEEK_CUR);
  886. // Allocate 4 channel buffers for Alpha, R, G, and B channels
  887. if (AllocateChannelBuffers((ulBottom-ulTop)*(ulRight-ulLeft)) != SUCCESS)
  888. TRACE("RLaymage::ReadLayerInfo - Error allocating channel buffers\n");
  889. return sReturn;
  890. }
  891. //////////////////////////////////////////////////////////////////////
  892. //
  893. // RLE_Decompress
  894. //
  895. // Description:
  896. // Decompress the RLE data using the algroithm from the Mac's
  897. // PackBits/UnpackBits routines. This function gets the file
  898. // pointer at the beginning of the RLE data, the size of the
  899. // compressed data to read (so it knows when to stop), and the
  900. // buffer that is already allocated large enough to hold the
  901. // decompressed data.
  902. //
  903. // Input:
  904. // char* pcBuffer = pointer to buffer large enough for the
  905. // decompressed data.
  906. // ulCompSize = size of compressed data
  907. // pcf = RFile pointer at the start of compressed data
  908. //
  909. // Output:
  910. // pcBuffer is filled with decompressed data
  911. //
  912. // Returns:
  913. // SUCCESS if decompressed successfully
  914. // FAILURE otherwise
  915. //
  916. //////////////////////////////////////////////////////////////////////
  917. short RLaymage::RLE_Decompress(char* pcBuffer, ULONG ulCompSize, RFile* pcfRLE)
  918. {
  919. short sReturn;
  920. ULONG ulRead = 0;
  921. ULONG ulBufferPos = 0;
  922. ULONG ulBufferFill = 0;
  923. signed char cData;
  924. signed char cFlag;
  925. UCHAR ucRun;
  926. USHORT i;
  927. if (pcfRLE && pcfRLE->IsOpen())
  928. {
  929. pcfRLE->ClearError();
  930. while (ulRead < ulCompSize)
  931. {
  932. pcfRLE->Read(&cFlag);
  933. ulRead++;
  934. if (cFlag < 0)
  935. {
  936. if (cFlag == 0x80)
  937. {
  938. pcfRLE->Read(&cData);
  939. ulRead++;
  940. }
  941. else
  942. {
  943. // Calculate number of a single byte pattern
  944. ucRun = -cFlag + 1;
  945. // Read the pattern
  946. pcfRLE->Read(&cData);
  947. ulRead++;
  948. for (i = 0; i < ucRun; i++)
  949. pcBuffer[ulBufferPos++] = cData;
  950. ulBufferFill += ucRun;
  951. }
  952. }
  953. else
  954. {
  955. // Read number of discrete bytes that follow
  956. ucRun = cFlag + 1;
  957. pcfRLE->Read(&(pcBuffer[ulBufferPos]), ucRun);
  958. ulBufferPos += ucRun;
  959. ulRead += ucRun;
  960. ulBufferFill += ucRun;
  961. }
  962. }
  963. if (pcfRLE->Error())
  964. sReturn = FAILURE;
  965. else
  966. sReturn = SUCCESS;
  967. }
  968. else
  969. sReturn = FAILURE;
  970. return sReturn;
  971. }
  972. //////////////////////////////////////////////////////////////////////
  973. //
  974. // ConvertToImage
  975. //
  976. // Description:
  977. // Takes the 4 channels of Photoshop data and converts it to a
  978. // 32-bit ARGB RImage. The Photoshop layers are saved not as
  979. // the whole image size, but a bounding rectangle that contains
  980. // information. So the bounding rectangle is passed in and will
  981. // be mapped on to a full size RImage layer.
  982. //
  983. // Parameters:
  984. // ulTop, ulBottom, ulLeft, ulRight = bounding rectangle for
  985. // the Photoshop data
  986. //
  987. // Returns:
  988. // SUCCESS if converted successfully
  989. // FAILURE otherwise
  990. //
  991. //////////////////////////////////////////////////////////////////////
  992. short RLaymage::ConvertToImage(short sLayerNum, ULONG ulTop, ULONG ulBottom,
  993. ULONG ulLeft, ULONG ulRight)
  994. {
  995. short sReturn = SUCCESS;
  996. RImage* pImage;
  997. ULONG row;
  998. ULONG col;
  999. ULONG i;
  1000. ULONG ulPixel;
  1001. pImage = m_apImages[sLayerNum] = new RImage(m_lWidth*m_lHeight*4);
  1002. if (pImage)
  1003. {
  1004. // Initialize buffer to Photoshop's style of blank which is
  1005. // white pixels that are totally transparent. This way if we read
  1006. // in a layer with a rectangle smaller than the total picture size,
  1007. // the outer regions will match.
  1008. U32* pu32 = (U32*) pImage->m_pData;
  1009. for (i = 0; i < pImage->m_ulSize / 4; i++)
  1010. pu32[i] = 0x00ffffff;
  1011. pImage->m_type = pImage->m_typeDestination = RImage::SCREEN32_ARGB;
  1012. pImage->m_sWidth = (short)m_lWidth;
  1013. pImage->m_sHeight = (short)m_lHeight;
  1014. pImage->m_sDepth = 32;
  1015. pImage->m_lPitch = (long)pImage->m_sWidth * (pImage->m_sDepth/8);
  1016. ULONG* ulp32 = (ULONG*) pImage->m_pData;
  1017. long lDestPitch = pImage->m_lPitch / 4;
  1018. i = 0;
  1019. for (row = ulTop; row < ulBottom; row++)
  1020. for (col = ulLeft; col < ulRight; col++)
  1021. {
  1022. ulPixel = ((UCHAR) m_pcChannels[LAYMAGE_ALPHA][i]) * 0x01000000 |
  1023. ((UCHAR) m_pcChannels[LAYMAGE_RED][i]) * 0x00010000 |
  1024. ((UCHAR) m_pcChannels[LAYMAGE_GREEN][i]) * 0x00000100 |
  1025. ((UCHAR) m_pcChannels[LAYMAGE_BLUE][i]);
  1026. i++;
  1027. ulp32[row*lDestPitch + col] = ulPixel;
  1028. }
  1029. }
  1030. return sReturn;
  1031. }
  1032. //////////////////////////////////////////////////////////////////////
  1033. //
  1034. // Load
  1035. //
  1036. // Description:
  1037. // The load functions take either a filename or an open RFile
  1038. // pointer and begin loading a CLamage file (,IML)
  1039. //
  1040. // Parameters:
  1041. // pszFilename = filename of the .IML file to be loaded - OR -
  1042. // CFile* pcf = pointer to open RFile where image loading starts
  1043. //
  1044. // Returns:
  1045. // SUCCESS if the file was loaded successfully
  1046. // FAILURE otherwise
  1047. //
  1048. //////////////////////////////////////////////////////////////////////
  1049. short RLaymage::Load(char* pszFilename)
  1050. {
  1051. RFile cf;
  1052. short sReturn = SUCCESS;
  1053. if (cf.Open(pszFilename, "rb", RFile::LittleEndian) != SUCCESS)
  1054. {
  1055. TRACE("RLaymage::Load - could not open file %s\n", pszFilename);
  1056. return FAILURE;
  1057. }
  1058. sReturn = Load(&cf);
  1059. cf.Close();
  1060. return sReturn;
  1061. }
  1062. short RLaymage::Load(RFile* pcf)
  1063. {
  1064. short sReturn = SUCCESS;
  1065. ULONG ulFileType = 0;
  1066. ULONG ulVersion = 0;
  1067. if (pcf && pcf->IsOpen())
  1068. {
  1069. if (pcf->Read(&ulFileType) == 1)
  1070. {
  1071. if (ulFileType == LAYMAGE_COOKIE)
  1072. {
  1073. if (pcf->Read(&ulVersion) == 1)
  1074. {
  1075. if (ulVersion == LAYMAGE_CURRENT_VERSION)
  1076. {
  1077. // Read number of layers and allocate memory
  1078. // Read layer names
  1079. // Use RImage to load the images
  1080. }
  1081. else
  1082. {
  1083. TRACE("RLaymage::Load - Error: File version is %d Current code version is %d\n", ulVersion, LAYMAGE_CURRENT_VERSION);
  1084. sReturn = FAILURE;
  1085. }
  1086. }
  1087. else
  1088. {
  1089. TRACE("RLaymage::Load - Error reading file version\n");
  1090. sReturn = FAILURE;
  1091. }
  1092. }
  1093. else
  1094. {
  1095. TRACE("RLaymage::Load - Error: File typs is not \"IML \"\n");
  1096. sReturn = FAILURE;
  1097. }
  1098. }
  1099. else
  1100. {
  1101. TRACE("RLaymage::Load - Error reading file type\n");
  1102. sReturn = FAILURE;
  1103. }
  1104. }
  1105. else
  1106. {
  1107. TRACE("RLaymage::Load - Error RFile pointer does not refer to an open file\n");
  1108. sReturn = FAILURE;
  1109. }
  1110. return sReturn;
  1111. }
  1112. //////////////////////////////////////////////////////////////////////
  1113. //
  1114. // Save
  1115. //
  1116. // Description:
  1117. // These functions save the RLaymage as its own file type (.IML)
  1118. // They save the layer names and use the RImage save to save each
  1119. // Image layer. One version takes a filename to save and the other
  1120. // version takes a pointer to an open RFile and writes the data where
  1121. // it is.
  1122. //
  1123. // Parameters:
  1124. // char* pszFilename = filename of the .IML file you wish to save - OR -
  1125. // RFile* pcf = pointer to an open RFile where the data will be saved
  1126. //
  1127. // Returns:
  1128. // SUCCESS if the file was saved
  1129. // FAILURE is there was an error -
  1130. // TRACE message will help pinpoint failure
  1131. //
  1132. //////////////////////////////////////////////////////////////////////
  1133. short RLaymage::Save(char* pszFilename)
  1134. {
  1135. RFile cf;
  1136. short sReturn = SUCCESS;
  1137. if (cf.Open(pszFilename, "wb", RFile::LittleEndian) != SUCCESS)
  1138. {
  1139. TRACE("RLaymage::Save - could not open file %s for output\n", pszFilename);
  1140. return FAILURE;
  1141. }
  1142. sReturn = Save(&cf);
  1143. cf.Close();
  1144. return sReturn;
  1145. }
  1146. short RLaymage::Save(RFile* /*pcf*/)
  1147. {
  1148. return FAILURE;
  1149. }
  1150. //////////////////////////////////////////////////////////////////////
  1151. //
  1152. // GetLayer
  1153. //
  1154. // Description:
  1155. // Returns a pointer to the RImage for the requested layer.
  1156. // This version of the function takes a string and tries to
  1157. // find a layer with the same name. If it finds it, it returns
  1158. // a pointer to the RImage for that layer.
  1159. //
  1160. // Parameters:
  1161. // pszLayerName = requested layer
  1162. //
  1163. // Returns:
  1164. // pointer to RImage of the requested layer if found
  1165. // NULL if not found
  1166. //
  1167. //////////////////////////////////////////////////////////////////////
  1168. RImage* RLaymage::GetLayer(char* pszLayerName)
  1169. {
  1170. short i = 0;
  1171. RImage* pLayerImage = NULL;
  1172. while (i < m_sNumLayers && pLayerImage == NULL)
  1173. {
  1174. if (strcmp(pszLayerName, m_apszLayerNames[i]) == 0)
  1175. {
  1176. pLayerImage = m_apImages[i];
  1177. if (pLayerImage == NULL)
  1178. {
  1179. ReadLayer(i);
  1180. pLayerImage = m_apImages[i];
  1181. }
  1182. }
  1183. else
  1184. i++;
  1185. }
  1186. return pLayerImage;
  1187. }
  1188. //////////////////////////////////////////////////////////////////////
  1189. //
  1190. // GetLayer
  1191. //
  1192. // Description:
  1193. // Returns a pointer to the RImage for the reuested layer.
  1194. // This version of the function takes a layer number and
  1195. // retuns a pointer to that layer (as long as it is a valid
  1196. // layer number).
  1197. //
  1198. // Parameters:
  1199. // sLayerNumber = number of the requested layer
  1200. //
  1201. // Returns:
  1202. // pointer to RImage of the requested layer if found
  1203. // NULL if not found
  1204. //
  1205. //////////////////////////////////////////////////////////////////////
  1206. RImage* RLaymage::GetLayer(short sLayerNumber)
  1207. {
  1208. RImage* pLayerImage = NULL;
  1209. if (sLayerNumber >= 0 && sLayerNumber < m_sNumLayers)
  1210. {
  1211. pLayerImage = m_apImages[sLayerNumber];
  1212. // If this layer is not in memory, load it in now
  1213. if (pLayerImage == NULL)
  1214. {
  1215. ReadLayer(sLayerNumber);
  1216. pLayerImage = m_apImages[sLayerNumber];
  1217. }
  1218. }
  1219. return pLayerImage;
  1220. }
  1221. //////////////////////////////////////////////////////////////////////
  1222. //
  1223. // FreeLayer
  1224. //
  1225. // Description:
  1226. // Frees the RImage for the specified layer. This version of the
  1227. // function takes the name of a layer and frees it as long as
  1228. // that layer exists.
  1229. //
  1230. // Parameters
  1231. // pszLayerName = name of layer to be freed
  1232. //
  1233. // Returns:
  1234. // none
  1235. //
  1236. //////////////////////////////////////////////////////////////////////
  1237. void RLaymage::FreeLayer(char* pszLayerName)
  1238. {
  1239. short i = 0;
  1240. short bFound = FALSE;
  1241. while (i < m_sNumLayers && !bFound)
  1242. {
  1243. if (strcmp(pszLayerName, m_apszLayerNames[i]) == 0)
  1244. bFound = TRUE;
  1245. else
  1246. i++;
  1247. }
  1248. if (bFound && m_apImages[i] != NULL)
  1249. {
  1250. delete m_apImages[i];
  1251. m_apImages[i] = NULL;
  1252. }
  1253. }
  1254. //////////////////////////////////////////////////////////////////////
  1255. //
  1256. // FreeLayer
  1257. //
  1258. // Description:
  1259. // Frees the RImage for the specified layer. This version of the
  1260. // function takes the layer number and frees it as long as that
  1261. // layer exists.
  1262. //
  1263. // Parameters
  1264. // sLayer = number of layer to be freed
  1265. //
  1266. // Returns:
  1267. // none
  1268. //
  1269. //////////////////////////////////////////////////////////////////////
  1270. void RLaymage::FreeLayer(short sLayerNumber)
  1271. {
  1272. if (sLayerNumber >= 0 && sLayerNumber < m_sNumLayers)
  1273. if (m_apImages[sLayerNumber])
  1274. {
  1275. delete m_apImages[sLayerNumber];
  1276. m_apImages[sLayerNumber] = NULL;
  1277. }
  1278. }
  1279. //////////////////////////////////////////////////////////////////////
  1280. //
  1281. // FreeAllLayers
  1282. //
  1283. // Description:
  1284. // Frees all of the RImage layers that have been allocated
  1285. //
  1286. // Parameters:
  1287. // none
  1288. //
  1289. // Returns:
  1290. // none
  1291. //
  1292. //////////////////////////////////////////////////////////////////////
  1293. void RLaymage::FreeAllLayers(void)
  1294. {
  1295. short i;
  1296. for (i = 0; i < m_sNumLayers; i++)
  1297. {
  1298. if (m_apImages[i])
  1299. {
  1300. delete m_apImages[i];
  1301. m_apImages[i] = NULL;
  1302. }
  1303. }
  1304. }
  1305. //////////////////////////////////////////////////////////////////////
  1306. //
  1307. // GetLayerName
  1308. //
  1309. // Description:
  1310. // Get the name of the requested layer
  1311. //
  1312. // Parameters:
  1313. // sLayer = Number of the layer
  1314. // pszNameBuffer = a buffer in which the name will be copied
  1315. //
  1316. // Returns:
  1317. // SUCCESS if the layer number given was valid
  1318. // FAILURE if that layer number does not exist or if the
  1319. // buffer passed in was NULL
  1320. //
  1321. //////////////////////////////////////////////////////////////////////
  1322. short RLaymage::GetLayerName(short sLayer, char* pszNameBuffer)
  1323. {
  1324. short sReturn = FAILURE;
  1325. if (pszNameBuffer && sLayer >= 0 && sLayer < m_sNumLayers)
  1326. {
  1327. strcpy(pszNameBuffer, m_apszLayerNames[sLayer]);
  1328. sReturn = SUCCESS;
  1329. }
  1330. return sReturn;
  1331. }
  1332. //////////////////////////////////////////////////////////////////////
  1333. //
  1334. // FreeLayerArrays
  1335. //
  1336. // Description:
  1337. // Frees the array of pointers to RImage and layer names along
  1338. // with the things they were pointing to. This is called to
  1339. // clean up the memory either by the destructor or if a new
  1340. // file is set or loaded.
  1341. //
  1342. // Parameters:
  1343. // none
  1344. //
  1345. // Returns:
  1346. // none
  1347. //
  1348. //////////////////////////////////////////////////////////////////////
  1349. void RLaymage::FreeLayerArrays(void)
  1350. {
  1351. if (m_apImages)
  1352. {
  1353. FreeAllLayers();
  1354. delete []m_apImages;
  1355. m_apImages = NULL;
  1356. }
  1357. if (m_apszLayerNames)
  1358. {
  1359. short i;
  1360. for (i = 0; i < m_sNumLayers; i++)
  1361. if (m_apszLayerNames[i])
  1362. delete []m_apszLayerNames[i];
  1363. delete []m_apszLayerNames;
  1364. m_apszLayerNames = NULL;
  1365. }
  1366. }
  1367. //////////////////////////////////////////////////////////////////////
  1368. //
  1369. // AllocateLayerArrays
  1370. //
  1371. // Description:
  1372. // Allocates the arrays of RImage pointers and string pointers
  1373. // for the layer names. It first calls FreeLayerArrays in
  1374. // case a file had already been loaded.
  1375. //
  1376. // Parameters:
  1377. // sNumLayers = number of pointers to allocate
  1378. //
  1379. // Returns:
  1380. // SUCCESS if the arrays were allocated successfully
  1381. // FAILURE otherwise
  1382. //
  1383. //////////////////////////////////////////////////////////////////////
  1384. short RLaymage::AllocateLayerArrays(short sNumLayers)
  1385. {
  1386. short sReturn = SUCCESS;
  1387. short i;
  1388. FreeLayerArrays();
  1389. m_apImages = new RImage*[m_sNumLayers];
  1390. if (m_apImages)
  1391. {
  1392. m_apszLayerNames = new char*[m_sNumLayers];
  1393. if (!m_apszLayerNames)
  1394. sReturn = FAILURE;
  1395. }
  1396. else
  1397. sReturn = FAILURE;
  1398. if (sReturn == SUCCESS)
  1399. {
  1400. for (i = 0; i < sNumLayers; i++)
  1401. {
  1402. m_apImages[i] = NULL;
  1403. m_apszLayerNames[i] = NULL;
  1404. }
  1405. }
  1406. return sReturn;
  1407. }
  1408. //////////////////////////////////////////////////////////////////////
  1409. // EOF
  1410. //////////////////////////////////////////////////////////////////////