File indexing completed on 2025-03-09 04:09:53
0001 /* Pixel and tile functions for xcftools 0002 * 0003 * This file was written by Henning Makholm <henning@makholm.net> 0004 * It is hereby in the public domain. 0005 * 0006 * In jurisdictions that do not recognise grants of copyright to the 0007 * public domain: I, the author and (presumably, in those jurisdictions) 0008 * copyright holder, hereby permit anyone to distribute and use this code, 0009 * in source code or binary form, with or without modifications. This 0010 * permission is world-wide and irrevocable. 0011 * 0012 * Of course, I will not be liable for any errors or shortcomings in the 0013 * code, since I give it away without asking any compenstations. 0014 * 0015 * If you use or distribute this code, I would appreciate receiving 0016 * credit for writing it, in whichever way you find proper and customary. 0017 */ 0018 0019 #ifndef PIXELS_H 0020 #define PIXELS_H 0021 0022 #include "xcftools.h" 0023 0024 /* MACROS FOR INTERNAL PIXEL ORDERING HERE */ 0025 /*=========================================*/ 0026 /* In principle the internal representation of pixels may change. 0027 * - this was supposed to allow an optimization where a layer could 0028 * be represented as a pointer into the mmapped xcf file, if 0029 * alignment, bpp, and endianness agreed (the point was that the 0030 * pixel representation had to agree with the endianness). 0031 * 0032 * However, it turns out that the current Gimp _always_ saves images 0033 * with RLE encoding of tiles, so such an effort would be in vain. 0034 * 0035 * Just for modularity, nevertheless try to isolate knowledge of 0036 * the RGBA-to-machine-word packing in this section of the 0037 * header file. Define new macros if necessary. 0038 * 0039 * Given that we don't have to agree with the uncompressed 0040 * RLE format, we choose to have the alpha in the _least_ 0041 * significant byte on all archs - it is tested and used more 0042 * often than the visible channels. 0043 */ 0044 typedef uint32_t rgba ; 0045 0046 #define ALPHA_SHIFT 0 0047 #define RED_SHIFT 8 0048 #define GREEN_SHIFT 16 0049 #define BLUE_SHIFT 24 0050 0051 #define ALPHA(rgba) ((uint8_t)(rgba)) 0052 #define FULLALPHA(rgba) ((uint8_t)(rgba) == 255) 0053 #define NULLALPHA(rgba) ((uint8_t)(rgba) == 0) 0054 #define NEWALPHA(rgb,a) (((rgba)(rgb) & 0xFFFFFF00) + (a)) 0055 0056 #ifdef PRECOMPUTED_SCALETABLE 0057 extern const uint8_t scaletable[256][256] ; 0058 #define INIT_SCALETABLE_IF(foo) ((void)0) 0059 #else 0060 extern uint8_t scaletable[256][256] ; 0061 extern int ok_scaletable ; 0062 void mk_scaletable(void); 0063 #define INIT_SCALETABLE_IF(foo) \ 0064 (ok_scaletable || !(foo) || (mk_scaletable(),0) ) 0065 #endif 0066 0067 extern const rgba graytable[256] ; 0068 extern rgba colormap[256] ; 0069 extern unsigned colormapLength ; 0070 int initLayer(struct xcfLayer *); 0071 int initColormap(); 0072 0073 int degrayPixel(rgba); /* returns -1 for non-gray pixels */ 0074 0075 /* ******************************************************* */ 0076 0077 #define TILEXn(dim,tx) \ 0078 ((tx)==(dim).tilesx ? (dim).c.r : (dim).c.l + ((tx)*TILE_WIDTH)) 0079 #define TILEYn(dim,ty) \ 0080 ((ty)==(dim).tilesy ? (dim).c.b : (dim).c.t + ((ty)*TILE_HEIGHT)) 0081 0082 #if defined(__i386__) 0083 /* This is probably the only common architecture where small constants 0084 * are more efficient for byte operations. 0085 */ 0086 typedef int8_t summary_t ; 0087 typedef short int refcount_t ; 0088 #else 0089 typedef int summary_t ; 0090 typedef int refcount_t ; 0091 #endif 0092 0093 #define TILESUMMARY_UPTODATE 8 0094 #define TILESUMMARY_ALLNULL 4 0095 #define TILESUMMARY_ALLFULL 2 0096 #define TILESUMMARY_CRISP 1 /* everything either null or full */ 0097 struct Tile { 0098 refcount_t refcount ; 0099 summary_t summary ; /* a combination of TIMESUMMARY_FOO constatns */ 0100 unsigned count ; 0101 rgba pixels[TILE_WIDTH * TILE_HEIGHT]; 0102 }; 0103 /* Actually, the Tile structures that get allocated many not have 0104 * room for that many pixels. We subtract the space for those we don't 0105 * use - which is Not Legal C, but ought to be portable. 0106 * OTOH, one can also use a static struct Tile for temporary storage. 0107 */ 0108 0109 0110 #define assertTileCompatibility(t1,t2) assert((t1)->count==(t2)->count) 0111 0112 struct Tile *newTile(struct rect); 0113 struct Tile *forkTile(struct Tile*); 0114 void freeTile(struct Tile*); 0115 #define invalidateSummary(tile,mask) \ 0116 do{ assert((tile)->refcount==1); (tile)->summary &= mask; } while(0) 0117 summary_t __ATTRIBUTE__((pure)) tileSummary(struct Tile *); 0118 0119 void fillTile(struct Tile*,rgba); 0120 0121 /* applyMask() destructively changes tile, 0122 * applyMask() gets ownership of mask 0123 */ 0124 void applyMask(struct Tile *tile, struct Tile *mask); 0125 0126 struct Tile *getLayerTile(struct xcfLayer *,const struct rect *); 0127 0128 struct Tile * getMaskOrLayerTile(struct tileDimensions *dim, struct xcfTiles *tiles, struct rect want); 0129 0130 #endif /* FLATTEN_H */