MultiGridIndirect.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  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. // MULTIGRIDINDIRECT.H
  21. //
  22. // Created on 05/01/97 JRD
  23. // Implemented 05/01/97 JRD
  24. //
  25. // History:
  26. //
  27. //
  28. //////////////////////////////////////////////////////////////////////
  29. #ifndef MULTIGRIDINDIRECT_H
  30. #define MULTIGRIDINDIRECT_H
  31. #include "System.h"
  32. #ifdef PATHS_IN_INCLUDES
  33. #include "BLUE/Blue.h"
  34. #include "ORANGE/File/file.h"
  35. #include "GREEN/Image/Image.h" // For Debugging only
  36. #include "GREEN/BLiT/BLIT.H"
  37. #include "ORANGE/MultiGrid/MultiGrid.h"
  38. #else
  39. #include "Blue.h"
  40. #include "file.h"
  41. #include "Image.h"
  42. #include "multigrid.h"
  43. #include "BLIT.H"
  44. #endif // PATHS_IN_INCLUDES
  45. #define MGI_COOKIE "_MultiGridIndirect_"
  46. #define MGI_CURRENT_VERSION 1
  47. #define MGI_MAX_PLANES 15 // to work wwith multigrid 15-bit
  48. // NOTE: zero is NOT a valid palette value, but it IS a valid attribute value
  49. //////////////////////////////////////////////////////////////////////
  50. //
  51. // CURRENT CONSTRAINTS (05/01/97)
  52. //
  53. // - Supports a maximum of 8 planes (bits)
  54. // - Supports a maximum of 8 palette entries per tile.
  55. // - Currently, the palette entries are PLANE based,
  56. // so a "hit" can be on all colors at once.
  57. //
  58. //
  59. // PLANNED ENHANCEMENTS
  60. //
  61. // - Template support for data of any type
  62. // - Switching between plane mode and linear mode
  63. // - Pascal Strings for data
  64. // - Higher speed access
  65. //
  66. //////////////////////////////////////////////////////////////////////
  67. //
  68. // TUNING PARAMETERS
  69. //
  70. // By turning off clipping, access speed is greatly enhanced
  71. //
  72. #define MGI_CLIP TRUE // undefine to turn off clip to world...
  73. //
  74. //////////////////////////////////////////////////////////////////////
  75. //////////////////////////////////////////////////////////////////////
  76. //
  77. // RMultiGridIndirect class
  78. //
  79. // This class provides higher compression than the standard
  80. // RMultigrid by adding one layer of indirection. It uses an
  81. // RMultigrid to look up a given 15-bit value. Then the lowest
  82. // 8 bits are viewed as 8 possible values from 0-256, which are
  83. // then looked up in the local "palette" table in the coarse grid.
  84. //
  85. // This is not as fast as RMultigrid, and should only be used in
  86. // limited amounts. Currently, the palette grid does NOT need to
  87. // line up in any way with the RMultigrid.
  88. //
  89. // Main data chuncks are the RMultiGrid, and a 2D palette grid, with
  90. // each entry currently 64-bits long (corresponding to 8 bytes)
  91. //
  92. //////////////////////////////////////////////////////////////////////
  93. class RMultiGridIndirect
  94. {
  95. public:
  96. //////////////////////////////////////////////////////////////////////
  97. // User members:
  98. //////////////////////////////////////////////////////////////////////
  99. short m_sWidth; // With compression, you might get huge objects!
  100. short m_sHeight;
  101. short m_sGridW;
  102. short m_sGridH;
  103. short m_sTileW;
  104. short m_sTileH;
  105. //////////////////////////////////////////////////////////////////////
  106. // User methods:
  107. //////////////////////////////////////////////////////////////////////
  108. // Due to the planar nature of the indirection, all values
  109. // may be present at the same time. Currently, you supply a
  110. // UCHAR array that is at least m_sMaxPlanes+1 in size. You
  111. // will recieve a NULL terminated string of dereferenced
  112. // palette hits for that point.
  113. //
  114. short GetVal(UCHAR* pszResult,short sX, short sY,char ucClipVal = -1)
  115. {
  116. //-----------------------------------------------------------------
  117. ASSERT(m_pmg);
  118. ASSERT(m_pucPalette);
  119. ASSERT(m_pmg->m_sIsCompressed);
  120. // 1) Get the set of index planes:
  121. USHORT usList = USHORT(m_pmg->GetVal(sX,sY,-1));
  122. // Check each plane individually
  123. for (short i=0;i < m_sMaxPlanes;i++)
  124. {
  125. if (usList & ms_asColorToPlane[i])
  126. *pszResult++ = *(GetPalette(sX,sY)+i); // look into clipping:
  127. }
  128. *pszResult = 0;
  129. return NULL;
  130. }
  131. // Load a compressed data set from disk
  132. //
  133. short Load(RFile* prFile);
  134. //////////////////////////////////////////////////////////////////////
  135. // Save a compressed data set to disk
  136. //
  137. short Save(RFile* prFile);
  138. //////////////////////////////////////////////////////////////////////
  139. // These user methods are for initially creating the 2d data
  140. //////////////////////////////////////////////////////////////////////
  141. // Returns SUCCESS or FAILURE
  142. // Sets up the UNCOMPRESSED data
  143. //
  144. short Alloc(short sW, short sH, short sMaxPlanes, short sTileW, short sTileH);
  145. //////////////////////////////////////////////////////////////////////
  146. // GetPalette (entire palette for that tile)
  147. //////////////////////////////////////////////////////////////////////
  148. // Low level palette access
  149. // Just get the current byte array of MGI_MAX_PLANES size:
  150. //
  151. UCHAR* GetPalette(short sX,short sY, UCHAR* pucOnError = NULL)
  152. {
  153. ASSERT(m_pucPalette);
  154. #ifdef MGI_CLIP
  155. if ( (sX < 0) || (sY < 0) || (sX >= m_sWidth) || (sY >= m_sHeight) )
  156. return pucOnError;
  157. #endif
  158. return m_ppucAccessY[sY] + m_plAccessX[sX];
  159. }
  160. // This gives you the number of taken palette entries in a tile:
  161. short NumPalEntries(short sX,short sY)
  162. {
  163. short sNumEntries = m_sMaxPlanes; // A Full Palette
  164. UCHAR* pPal = GetPalette(sX,sY) + m_sMaxPlanes;
  165. while (sNumEntries && (!*--pPal)) sNumEntries--;
  166. return sNumEntries;
  167. }
  168. //////////////////////////////////////////////////////////////////////
  169. // "Install" the RMultiGrid which holds the index data:
  170. // (This must not be compressed until it is done being written to)
  171. //////////////////////////////////////////////////////////////////////
  172. short InstallMultiGrid(RMultiGrid* pmg)
  173. {
  174. ASSERT(!m_pmg);
  175. ASSERT(pmg);
  176. ASSERT( (pmg->m_sWidth == m_sWidth) && (pmg->m_sHeight == m_sHeight));
  177. ASSERT(!pmg->m_sIsCompressed);
  178. m_pmg = pmg;
  179. return SUCCESS;
  180. }
  181. //////////////////////////////////////////////////////////////////////
  182. // SetPalette (Set an entry in that tile's palette)
  183. //////////////////////////////////////////////////////////////////////
  184. // Low level palette access
  185. // Just set the current byte palette entry
  186. //
  187. short SetPalette(short sX,short sY,short sEntry,UCHAR ucVal)
  188. {
  189. ASSERT(m_pucPalette);
  190. #ifdef MGI_CLIP
  191. if ( (sX < 0) || (sY < 0) || (sX >= m_sWidth) || (sY >= m_sHeight) )
  192. return -1;
  193. #endif
  194. *(m_ppucAccessY[sY] + m_plAccessX[sX] + sEntry) = ucVal;
  195. return SUCCESS;
  196. }
  197. // A visual Debug View: (Uncompressed)
  198. //
  199. void DumpPalette(RImage* pimDst,short sSrcX,short sSrcY,short sDstX,short sDstY,
  200. short sW,short sH);
  201. //////////////////////////////////////////////////////////////////////
  202. // Internal methods:
  203. //////////////////////////////////////////////////////////////////////
  204. void Clear()
  205. {
  206. m_sWidth = m_sHeight = m_sGridW = m_sGridH = m_sTileW = m_sTileH = 0;
  207. m_pmg = NULL;
  208. m_pucPalette = NULL;
  209. m_ppucAccessY = NULL;
  210. m_plAccessX = NULL;
  211. m_pimTempTile = NULL;
  212. m_lTileLen = 0;
  213. m_pimBuffer = NULL;
  214. }
  215. void Free()
  216. {
  217. //if (m_pmg) delete m_pmg;// Let user delete MultiGrid
  218. if (m_pucPalette) free(m_pucPalette);
  219. if (m_ppucAccessY) free (m_ppucAccessY);
  220. if (m_plAccessX) free(m_plAccessX);
  221. if (m_pimTempTile) delete m_pimTempTile;
  222. if (m_pimBuffer) delete m_pimBuffer;
  223. if (m_pmg) delete m_pmg;
  224. Clear();
  225. }
  226. RMultiGridIndirect()
  227. {
  228. Clear();
  229. }
  230. ~RMultiGridIndirect()
  231. {
  232. Free();
  233. }
  234. /////////////////////////////////////////////////////////////////////
  235. // Some of the following functions operate on both RMultiAlphas
  236. // AND the palette grid. Here we leave the realm of pure Orange,
  237. // and the realm of general functions. Once general use of the
  238. // IndirectMultigrid is understood, this should be separated out.
  239. /////////////////////////////////////////////////////////////////////
  240. // This clear the temp tile buffer first to allow the possibility of
  241. // source clipping: (It does an opaque copy)
  242. void CacheTile(RImage* pimSrc,short sSrcX,short sSrcY)
  243. {
  244. // 1) clear buffer tile:
  245. memset(m_pimTempTile->m_pData,0,m_lTileLen);
  246. // 2) do a fully clipping opaque copy into the temp tile:
  247. RRect rrect(0,0,pimSrc->m_sWidth,pimSrc->m_sHeight);
  248. rspBlit(pimSrc,m_pimTempTile,sSrcX,sSrcY,0,0,
  249. m_sTileW,m_sTileH,NULL,&rrect);
  250. }
  251. // This is a linear check to see if you have a null cache:
  252. short Contains(UCHAR ucColor)
  253. {
  254. UCHAR *pTile = m_pimTempTile->m_pData;
  255. for (short i=0; i < m_lTileLen; i++,pTile++)
  256. if (*pTile == ucColor) return TRUE;
  257. return FALSE;
  258. }
  259. // This is a highly specialized OR blit into the uncompressed
  260. // attribute map! It goes from an 8-bit source key to a 15-bit
  261. // destination key:
  262. // It will only do RIGHT AND BOTTOM CLIPPING!
  263. //
  264. void TileOR(UCHAR ucKey,USHORT usValueOR,short sDstX,short sDstY,
  265. short sClip = 0); // you can turn off the half clipping:
  266. // Drop an FSPR1 into the Attribute map:
  267. //
  268. short AddFSPR1(RImage* pimSrc,short sX,short sY,UCHAR ucVal,
  269. short sMaxW=0,short sMaxH=0);
  270. public:
  271. //////////////////////////////////////////////////////////////////////
  272. // Data Structures
  273. //////////////////////////////////////////////////////////////////////
  274. RMultiGrid* m_pmg; // The MultiGrid inherent under the system
  275. UCHAR* m_pucPalette; // Data holding the palette entries
  276. UCHAR** m_ppucAccessY; // Array of (GridH) pointers into the Palette
  277. ULONG* m_plAccessX; // Array of offsets into the Palette
  278. short m_sMaxPlanes; // Can be custom tailored to save memory
  279. RImage* m_pimTempTile; // For construction & easy writing.
  280. RImage* m_pimBuffer; // Large conversion buffer
  281. long m_lTileLen; // For linear operations
  282. static short ms_asColorToPlane[MGI_MAX_PLANES];
  283. };
  284. #endif //MULTIGRIDINDIRECT_H
  285. //////////////////////////////////////////////////////////////////////
  286. // EOF
  287. //////////////////////////////////////////////////////////////////////