MCPcopy Create free account
hub / github.com/MapServer/MapServer / remapPaletteForPNG

Function remapPaletteForPNG

mapimageio.c:194–250  ·  view source on GitHub ↗

* sort a given list of rgba entries so that all the opaque pixels are at the end */

Source from the content-addressed store, hash-verified

192 * sort a given list of rgba entries so that all the opaque pixels are at the end
193 */
194int remapPaletteForPNG(rasterBufferObj *rb, rgbPixel *rgb, unsigned char *a, int *num_a) {
195 int bot_idx, top_idx, x;
196 int remap[256];
197 unsigned int maxval = rb->data.palette.scaling_maxval;
198
199 assert(rb->type == MS_BUFFER_BYTE_PALETTE);
200
201 /*
202 ** remap the palette colors so that all entries with
203 ** the maximal alpha value (i.e., fully opaque) are at the end and can
204 ** therefore be omitted from the tRNS chunk. Note that the ordering of
205 ** opaque entries is reversed from how they were previously arranged
206 ** --not that this should matter to anyone.
207 */
208
209 for (top_idx = rb->data.palette.num_entries-1, bot_idx = x = 0; x < rb->data.palette.num_entries; ++x) {
210 if (rb->data.palette.palette[x].a == maxval)
211 remap[x] = top_idx--;
212 else
213 remap[x] = bot_idx++;
214 }
215 /* sanity check: top and bottom indices should have just crossed paths */
216 if (bot_idx != top_idx + 1) {
217 msSetError(MS_MISCERR,"quantization sanity check failed","createPNGPalette()");
218 return MS_FAILURE;
219 }
220
221 *num_a = bot_idx;
222
223 for(x=0;x<rb->width*rb->height;x++)
224 rb->data.palette.pixels[x] = remap[rb->data.palette.pixels[x]];
225
226
227 for (x = 0; x < rb->data.palette.num_entries; ++x) {
228 if(maxval == 255) {
229 a[remap[x]] = rb->data.palette.palette[x].a;
230 rgb[remap[x]].r = rb->data.palette.palette[x].r;
231 rgb[remap[x]].g = rb->data.palette.palette[x].g;
232 rgb[remap[x]].b = rb->data.palette.palette[x].b;
233 } else {
234 /* rescale palette */
235 rgb[remap[x]].r = (rb->data.palette.palette[x].r * 255 + (maxval >> 1)) / maxval;
236 rgb[remap[x]].g = (rb->data.palette.palette[x].g * 255 + (maxval >> 1)) / maxval;
237 rgb[remap[x]].b = (rb->data.palette.palette[x].b * 255 + (maxval >> 1)) / maxval;
238 a[remap[x]] = (rb->data.palette.palette[x].a * 255 + (maxval >> 1)) / maxval;
239 }
240 if(a[remap[x]] != 255) {
241 /* un-premultiply pixels */
242 double da = 255.0/a[remap[x]];
243 rgb[remap[x]].r *= da;
244 rgb[remap[x]].g *= da;
245 rgb[remap[x]].b *= da;
246 }
247 }
248
249 return MS_SUCCESS;
250}
251

Callers 1

savePalettePNGFunction · 0.85

Calls 1

msSetErrorFunction · 0.85

Tested by

no test coverage detected