123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Copyright 2016 RWS Inc, All Rights Reserved
- //
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of version 2 of the GNU General Public License as published by
- // the Free Software Foundation
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License along
- // with this program; if not, write to the Free Software Foundation, Inc.,
- // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- //
- //////////////////////////////////////////////////////////////////////
- //
- // MULTIGRIDINDIRECT.H
- //
- // Created on 05/01/97 JRD
- // Implemented 05/01/97 JRD
- //
- // History:
- //
- //
- //////////////////////////////////////////////////////////////////////
- #ifndef MULTIGRIDINDIRECT_H
- #define MULTIGRIDINDIRECT_H
- #include "System.h"
- #ifdef PATHS_IN_INCLUDES
- #include "BLUE/Blue.h"
- #include "ORANGE/File/file.h"
- #include "GREEN/Image/Image.h" // For Debugging only
- #include "GREEN/BLiT/BLIT.H"
- #include "ORANGE/MultiGrid/MultiGrid.h"
- #else
- #include "Blue.h"
- #include "file.h"
- #include "Image.h"
- #include "multigrid.h"
- #include "BLIT.H"
- #endif // PATHS_IN_INCLUDES
-
- #define MGI_COOKIE "_MultiGridIndirect_"
- #define MGI_CURRENT_VERSION 1
- #define MGI_MAX_PLANES 15 // to work wwith multigrid 15-bit
- // NOTE: zero is NOT a valid palette value, but it IS a valid attribute value
- //////////////////////////////////////////////////////////////////////
- //
- // CURRENT CONSTRAINTS (05/01/97)
- //
- // - Supports a maximum of 8 planes (bits)
- // - Supports a maximum of 8 palette entries per tile.
- // - Currently, the palette entries are PLANE based,
- // so a "hit" can be on all colors at once.
- //
- //
- // PLANNED ENHANCEMENTS
- //
- // - Template support for data of any type
- // - Switching between plane mode and linear mode
- // - Pascal Strings for data
- // - Higher speed access
- //
- //////////////////////////////////////////////////////////////////////
- //
- // TUNING PARAMETERS
- //
- // By turning off clipping, access speed is greatly enhanced
- //
- #define MGI_CLIP TRUE // undefine to turn off clip to world...
- //
- //////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////
- //
- // RMultiGridIndirect class
- //
- // This class provides higher compression than the standard
- // RMultigrid by adding one layer of indirection. It uses an
- // RMultigrid to look up a given 15-bit value. Then the lowest
- // 8 bits are viewed as 8 possible values from 0-256, which are
- // then looked up in the local "palette" table in the coarse grid.
- //
- // This is not as fast as RMultigrid, and should only be used in
- // limited amounts. Currently, the palette grid does NOT need to
- // line up in any way with the RMultigrid.
- //
- // Main data chuncks are the RMultiGrid, and a 2D palette grid, with
- // each entry currently 64-bits long (corresponding to 8 bytes)
- //
- //////////////////////////////////////////////////////////////////////
- class RMultiGridIndirect
- {
- public:
- //////////////////////////////////////////////////////////////////////
- // User members:
- //////////////////////////////////////////////////////////////////////
- short m_sWidth; // With compression, you might get huge objects!
- short m_sHeight;
- short m_sGridW;
- short m_sGridH;
- short m_sTileW;
- short m_sTileH;
- //////////////////////////////////////////////////////////////////////
- // User methods:
- //////////////////////////////////////////////////////////////////////
- // Due to the planar nature of the indirection, all values
- // may be present at the same time. Currently, you supply a
- // UCHAR array that is at least m_sMaxPlanes+1 in size. You
- // will recieve a NULL terminated string of dereferenced
- // palette hits for that point.
- //
- short GetVal(UCHAR* pszResult,short sX, short sY,char ucClipVal = -1)
- {
- //-----------------------------------------------------------------
- ASSERT(m_pmg);
- ASSERT(m_pucPalette);
- ASSERT(m_pmg->m_sIsCompressed);
- // 1) Get the set of index planes:
- USHORT usList = USHORT(m_pmg->GetVal(sX,sY,-1));
- // Check each plane individually
- for (short i=0;i < m_sMaxPlanes;i++)
- {
- if (usList & ms_asColorToPlane[i])
- *pszResult++ = *(GetPalette(sX,sY)+i); // look into clipping:
- }
- *pszResult = 0;
- return NULL;
- }
- // Load a compressed data set from disk
- //
- short Load(RFile* prFile);
- //////////////////////////////////////////////////////////////////////
- // Save a compressed data set to disk
- //
- short Save(RFile* prFile);
-
- //////////////////////////////////////////////////////////////////////
- // These user methods are for initially creating the 2d data
- //////////////////////////////////////////////////////////////////////
- // Returns SUCCESS or FAILURE
- // Sets up the UNCOMPRESSED data
- //
- short Alloc(short sW, short sH, short sMaxPlanes, short sTileW, short sTileH);
- //////////////////////////////////////////////////////////////////////
- // GetPalette (entire palette for that tile)
- //////////////////////////////////////////////////////////////////////
- // Low level palette access
- // Just get the current byte array of MGI_MAX_PLANES size:
- //
- UCHAR* GetPalette(short sX,short sY, UCHAR* pucOnError = NULL)
- {
- ASSERT(m_pucPalette);
- #ifdef MGI_CLIP
- if ( (sX < 0) || (sY < 0) || (sX >= m_sWidth) || (sY >= m_sHeight) )
- return pucOnError;
- #endif
- return m_ppucAccessY[sY] + m_plAccessX[sX];
- }
- // This gives you the number of taken palette entries in a tile:
- short NumPalEntries(short sX,short sY)
- {
- short sNumEntries = m_sMaxPlanes; // A Full Palette
- UCHAR* pPal = GetPalette(sX,sY) + m_sMaxPlanes;
- while (sNumEntries && (!*--pPal)) sNumEntries--;
- return sNumEntries;
- }
- //////////////////////////////////////////////////////////////////////
- // "Install" the RMultiGrid which holds the index data:
- // (This must not be compressed until it is done being written to)
- //////////////////////////////////////////////////////////////////////
- short InstallMultiGrid(RMultiGrid* pmg)
- {
- ASSERT(!m_pmg);
- ASSERT(pmg);
- ASSERT( (pmg->m_sWidth == m_sWidth) && (pmg->m_sHeight == m_sHeight));
- ASSERT(!pmg->m_sIsCompressed);
- m_pmg = pmg;
- return SUCCESS;
- }
- //////////////////////////////////////////////////////////////////////
- // SetPalette (Set an entry in that tile's palette)
- //////////////////////////////////////////////////////////////////////
- // Low level palette access
- // Just set the current byte palette entry
- //
- short SetPalette(short sX,short sY,short sEntry,UCHAR ucVal)
- {
- ASSERT(m_pucPalette);
- #ifdef MGI_CLIP
- if ( (sX < 0) || (sY < 0) || (sX >= m_sWidth) || (sY >= m_sHeight) )
- return -1;
- #endif
- *(m_ppucAccessY[sY] + m_plAccessX[sX] + sEntry) = ucVal;
- return SUCCESS;
- }
- // A visual Debug View: (Uncompressed)
- //
- void DumpPalette(RImage* pimDst,short sSrcX,short sSrcY,short sDstX,short sDstY,
- short sW,short sH);
- //////////////////////////////////////////////////////////////////////
- // Internal methods:
- //////////////////////////////////////////////////////////////////////
- void Clear()
- {
- m_sWidth = m_sHeight = m_sGridW = m_sGridH = m_sTileW = m_sTileH = 0;
- m_pmg = NULL;
- m_pucPalette = NULL;
- m_ppucAccessY = NULL;
- m_plAccessX = NULL;
- m_pimTempTile = NULL;
- m_lTileLen = 0;
- m_pimBuffer = NULL;
- }
- void Free()
- {
- //if (m_pmg) delete m_pmg;// Let user delete MultiGrid
- if (m_pucPalette) free(m_pucPalette);
- if (m_ppucAccessY) free (m_ppucAccessY);
- if (m_plAccessX) free(m_plAccessX);
- if (m_pimTempTile) delete m_pimTempTile;
- if (m_pimBuffer) delete m_pimBuffer;
- if (m_pmg) delete m_pmg;
- Clear();
- }
- RMultiGridIndirect()
- {
- Clear();
- }
- ~RMultiGridIndirect()
- {
- Free();
- }
- /////////////////////////////////////////////////////////////////////
- // Some of the following functions operate on both RMultiAlphas
- // AND the palette grid. Here we leave the realm of pure Orange,
- // and the realm of general functions. Once general use of the
- // IndirectMultigrid is understood, this should be separated out.
- /////////////////////////////////////////////////////////////////////
- // This clear the temp tile buffer first to allow the possibility of
- // source clipping: (It does an opaque copy)
- void CacheTile(RImage* pimSrc,short sSrcX,short sSrcY)
- {
- // 1) clear buffer tile:
- memset(m_pimTempTile->m_pData,0,m_lTileLen);
- // 2) do a fully clipping opaque copy into the temp tile:
- RRect rrect(0,0,pimSrc->m_sWidth,pimSrc->m_sHeight);
- rspBlit(pimSrc,m_pimTempTile,sSrcX,sSrcY,0,0,
- m_sTileW,m_sTileH,NULL,&rrect);
- }
- // This is a linear check to see if you have a null cache:
- short Contains(UCHAR ucColor)
- {
- UCHAR *pTile = m_pimTempTile->m_pData;
- for (short i=0; i < m_lTileLen; i++,pTile++)
- if (*pTile == ucColor) return TRUE;
- return FALSE;
- }
- // This is a highly specialized OR blit into the uncompressed
- // attribute map! It goes from an 8-bit source key to a 15-bit
- // destination key:
- // It will only do RIGHT AND BOTTOM CLIPPING!
- //
- void TileOR(UCHAR ucKey,USHORT usValueOR,short sDstX,short sDstY,
- short sClip = 0); // you can turn off the half clipping:
- // Drop an FSPR1 into the Attribute map:
- //
- short AddFSPR1(RImage* pimSrc,short sX,short sY,UCHAR ucVal,
- short sMaxW=0,short sMaxH=0);
- public:
- //////////////////////////////////////////////////////////////////////
- // Data Structures
- //////////////////////////////////////////////////////////////////////
- RMultiGrid* m_pmg; // The MultiGrid inherent under the system
- UCHAR* m_pucPalette; // Data holding the palette entries
- UCHAR** m_ppucAccessY; // Array of (GridH) pointers into the Palette
- ULONG* m_plAccessX; // Array of offsets into the Palette
- short m_sMaxPlanes; // Can be custom tailored to save memory
- RImage* m_pimTempTile; // For construction & easy writing.
- RImage* m_pimBuffer; // Large conversion buffer
- long m_lTileLen; // For linear operations
- static short ms_asColorToPlane[MGI_MAX_PLANES];
- };
- #endif //MULTIGRIDINDIRECT_H
- //////////////////////////////////////////////////////////////////////
- // EOF
- //////////////////////////////////////////////////////////////////////
|