annotate src/filters/pixel.cpp @ 68:86093f2ce7d1

got the speedrun to play
author Robert McIntyre <rlm@mit.edu>
date Thu, 08 Mar 2012 02:10:03 -0600
parents f9f4f1b99eed
children
rev   line source
rlm@1 1 #include "../Port.h"
rlm@1 2
rlm@1 3 extern u32 RGB_LOW_BITS_MASK;
rlm@1 4
rlm@1 5 void Pixelate2x16(u8 *srcPtr, u32 srcPitch, u8 *deltaPtr,
rlm@1 6 u8 *dstPtr, u32 dstPitch, int width, int height)
rlm@1 7 {
rlm@1 8 u8 *nextLine, *finish;
rlm@1 9 u32 colorMask = ~(RGB_LOW_BITS_MASK | (RGB_LOW_BITS_MASK << 16));
rlm@1 10 colorMask = (colorMask >> 2) & (colorMask >> 1);
rlm@1 11
rlm@1 12 nextLine = dstPtr + dstPitch;
rlm@1 13
rlm@1 14 do
rlm@1 15 {
rlm@1 16 u32 *bP = (u32 *) srcPtr;
rlm@1 17 u32 *xP = (u32 *) deltaPtr;
rlm@1 18 u32 *dP = (u32 *) dstPtr;
rlm@1 19 u32 *nL = (u32 *) nextLine;
rlm@1 20 u32 currentPixel;
rlm@1 21 u32 nextPixel;
rlm@1 22 u32 currentDelta;
rlm@1 23 u32 nextDelta;
rlm@1 24
rlm@1 25 finish = (u8 *) bP + ((width+2) << 1);
rlm@1 26 nextPixel = *bP++;
rlm@1 27 nextDelta = *xP++;
rlm@1 28
rlm@1 29 do
rlm@1 30 {
rlm@1 31 currentPixel = nextPixel;
rlm@1 32 currentDelta = nextDelta;
rlm@1 33 nextPixel = *bP++;
rlm@1 34 nextDelta = *xP++;
rlm@1 35
rlm@1 36 if ((nextPixel != nextDelta) || (currentPixel != currentDelta))
rlm@1 37 {
rlm@1 38 u32 colorA, colorB, product;
rlm@1 39
rlm@1 40 *(xP - 2) = currentPixel;
rlm@1 41 #ifdef WORDS_BIGENDIAN
rlm@1 42 colorA = currentPixel >> 16;
rlm@1 43 colorB = currentPixel & 0xffff;
rlm@1 44 #else
rlm@1 45 colorA = currentPixel & 0xffff;
rlm@1 46 colorB = currentPixel >> 16;
rlm@1 47 #endif
rlm@1 48 product = (colorA >> 2) & colorMask;
rlm@1 49
rlm@1 50 #ifdef WORDS_BIGENDIAN
rlm@1 51 *(nL) = (product << 16) | (product);
rlm@1 52 *(dP) = (colorA << 16) | product;
rlm@1 53 #else
rlm@1 54 *(nL) = product | (product << 16);
rlm@1 55 *(dP) = colorA | (product << 16);
rlm@1 56 #endif
rlm@1 57
rlm@1 58 #ifdef WORDS_BIGENDIAN
rlm@1 59 colorA = nextPixel >> 16;
rlm@1 60 #else
rlm@1 61 colorA = nextPixel & 0xffff;
rlm@1 62 #endif
rlm@1 63 product = (colorB >> 2) & colorMask;
rlm@1 64 #ifdef WORDS_BIGENDIAN
rlm@1 65 *(nL + 1) = (product << 16) | (product);
rlm@1 66 *(dP + 1) = (colorB << 16) | (product);
rlm@1 67 #else
rlm@1 68 *(nL + 1) = (product) | (product << 16);
rlm@1 69 *(dP + 1) = (colorB) | (product << 16);
rlm@1 70 #endif
rlm@1 71 }
rlm@1 72
rlm@1 73 dP += 2;
rlm@1 74 nL += 2;
rlm@1 75 }
rlm@1 76 while ((u8 *) bP < finish);
rlm@1 77
rlm@1 78 deltaPtr += srcPitch;
rlm@1 79 srcPtr += srcPitch;
rlm@1 80 dstPtr += dstPitch << 1;
rlm@1 81 nextLine += dstPitch << 1;
rlm@1 82 }
rlm@1 83 while (--height);
rlm@1 84 }
rlm@1 85
rlm@1 86 void Pixelate2x32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
rlm@1 87 u8 *dstPtr, u32 dstPitch, int width, int height)
rlm@1 88 {
rlm@1 89 u8 *nextLine, *finish;
rlm@1 90 u32 colorMask = ((u32)~RGB_LOW_BITS_MASK >> 2) & ((u32)~RGB_LOW_BITS_MASK >> 1);
rlm@1 91
rlm@1 92 nextLine = dstPtr + dstPitch;
rlm@1 93
rlm@1 94 do
rlm@1 95 {
rlm@1 96 u32 *bP = (u32 *) srcPtr;
rlm@1 97 // u32 *xP = (u32 *) deltaPtr;
rlm@1 98 u32 *dP = (u32 *) dstPtr;
rlm@1 99 u32 *nL = (u32 *) nextLine;
rlm@1 100 u32 currentPixel;
rlm@1 101 u32 nextPixel;
rlm@1 102
rlm@1 103 finish = (u8 *) bP + ((width+1) << 2);
rlm@1 104 nextPixel = *bP++;
rlm@1 105
rlm@1 106 do
rlm@1 107 {
rlm@1 108 u32 product;
rlm@1 109
rlm@1 110 currentPixel = nextPixel;
rlm@1 111 nextPixel = *bP++;
rlm@1 112 product = (currentPixel >> 2) & colorMask;
rlm@1 113 *(nL) = product;
rlm@1 114 *(nL+1) = product;
rlm@1 115 *(dP) = currentPixel;
rlm@1 116 *(dP+1) = product;
rlm@1 117
rlm@1 118 currentPixel = nextPixel;
rlm@1 119 nextPixel = *bP++;
rlm@1 120 product = (currentPixel >> 2) & colorMask;
rlm@1 121 *(nL + 2) = product;
rlm@1 122 *(nL + 3) = product;
rlm@1 123 *(dP + 2) = currentPixel;
rlm@1 124 *(dP + 3) = product;
rlm@1 125
rlm@1 126 dP += 4;
rlm@1 127 nL += 4;
rlm@1 128 }
rlm@1 129 while ((u8 *) bP < finish);
rlm@1 130
rlm@1 131 srcPtr += srcPitch;
rlm@1 132 dstPtr += dstPitch << 1;
rlm@1 133 nextLine += dstPitch << 1;
rlm@1 134 }
rlm@1 135 while (--height);
rlm@1 136 }
rlm@1 137
rlm@1 138 // generic Pixelate Nx magnification filter
rlm@1 139 template <int magnification, typename ColorType>
rlm@1 140 void PixelateNx(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
rlm@1 141 u8 *dstPtr, u32 dstPitch, int width, int height)
rlm@1 142 {
rlm@1 143 ColorType colorMask = ((ColorType)~RGB_LOW_BITS_MASK >> 2) & ((ColorType)~RGB_LOW_BITS_MASK >> 1);
rlm@1 144
rlm@1 145 srcPitch = srcPitch / sizeof(ColorType) - width;
rlm@1 146 u32 dstNextP = dstPitch / sizeof(ColorType);
rlm@1 147 u32 dstNextL = (dstNextP - width) * magnification; // skip to the next magnificated 'line'
rlm@1 148 dstNextP -= magnification;
rlm@1 149
rlm@1 150 u32 offset = (dstPitch + sizeof(ColorType)) * magnification - dstPitch;
rlm@1 151
rlm@1 152 ColorType *src = (ColorType *)srcPtr;
rlm@1 153 ColorType *dst = (ColorType *)dstPtr;
rlm@1 154
rlm@1 155 do // per src line
rlm@1 156 {
rlm@1 157 u8 *finishP = (u8 *)dst + offset;
rlm@1 158 for (int x = 0; x < width; ++x) // per pixel in line
rlm@1 159 {
rlm@1 160 ColorType col = *src;
rlm@1 161 ColorType *dst2 = dst;
rlm@1 162 u8 *finishM = (u8 *)(dst + magnification);
rlm@1 163
rlm@1 164 ColorType product = (col >> 2) & colorMask;
rlm@1 165 do
rlm@1 166 {
rlm@1 167 *dst2 = product;
rlm@1 168 } while ((u8 *)++dst2 < finishM);
rlm@1 169 dst2 += dstNextP;
rlm@1 170 finishM += dstPitch;
rlm@1 171 do // dst magnificated pixel
rlm@1 172 {
rlm@1 173 *dst2++ = product;
rlm@1 174 do
rlm@1 175 {
rlm@1 176 *dst2 = col;
rlm@1 177 } while ((u8 *)++dst2 < finishM);
rlm@1 178 dst2 += dstNextP;
rlm@1 179 finishM += dstPitch;
rlm@1 180 } while ((u8 *)dst2 < finishP);
rlm@1 181
rlm@1 182 ++src;
rlm@1 183 dst += magnification;
rlm@1 184 finishP += magnification * sizeof(ColorType);
rlm@1 185 }
rlm@1 186 src += srcPitch;
rlm@1 187 dst += dstNextL;
rlm@1 188 } while (--height);
rlm@1 189 }
rlm@1 190
rlm@1 191 typedef void (*PixelateNxFP)(u8*, u32, u8*, u8*, u32, int, int);
rlm@1 192
rlm@1 193 PixelateNxFP Pixelate3x16 = PixelateNx<3, u16>;
rlm@1 194 PixelateNxFP Pixelate3x32 = PixelateNx<3, u32>;
rlm@1 195 PixelateNxFP Pixelate4x16 = PixelateNx<4, u16>;
rlm@1 196 PixelateNxFP Pixelate4x32 = PixelateNx<4, u32>;