Mercurial > sdl-ios-xcode
comparison src/video/SDL_pixels.c @ 1683:396a35389351 SDL-1.3
Finished palettized display handling.
Added support for surface palette sharing.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 17 Jun 2006 06:45:14 +0000 |
parents | 7ae8018b2e5d |
children | 1577404809f0 |
comparison
equal
deleted
inserted
replaced
1682:7ae8018b2e5d | 1683:396a35389351 |
---|---|
213 } | 213 } |
214 } | 214 } |
215 return SDL_PixelFormat_Unknown; | 215 return SDL_PixelFormat_Unknown; |
216 } | 216 } |
217 | 217 |
218 | |
219 SDL_Palette * | |
220 SDL_AllocPalette(int ncolors) | |
221 { | |
222 SDL_Palette *palette; | |
223 | |
224 palette = (SDL_Palette *) SDL_malloc(sizeof(*palette)); | |
225 if (!palette) { | |
226 SDL_OutOfMemory(); | |
227 return NULL; | |
228 } | |
229 palette->colors = | |
230 (SDL_Color *) SDL_malloc(ncolors * sizeof(*palette->colors)); | |
231 if (!palette->colors) { | |
232 SDL_free(palette); | |
233 return NULL; | |
234 } | |
235 palette->ncolors = ncolors; | |
236 palette->watch = NULL; | |
237 palette->refcount = 1; | |
238 | |
239 SDL_memset(palette->colors, 0xFF, ncolors * sizeof(*palette->colors)); | |
240 | |
241 return palette; | |
242 } | |
243 | |
244 int | |
245 SDL_AddPaletteWatch(SDL_Palette * palette, SDL_PaletteChangedFunc callback, | |
246 void *userdata) | |
247 { | |
248 SDL_PaletteWatch *watch; | |
249 | |
250 if (!palette) { | |
251 return -1; | |
252 } | |
253 | |
254 watch = (SDL_PaletteWatch *) SDL_malloc(sizeof(*watch)); | |
255 if (!watch) { | |
256 SDL_OutOfMemory(); | |
257 return -1; | |
258 } | |
259 | |
260 watch->callback = callback; | |
261 watch->userdata = userdata; | |
262 watch->next = palette->watch; | |
263 palette->watch = watch; | |
264 ++palette->refcount; | |
265 return 0; | |
266 } | |
267 | |
268 void | |
269 SDL_DelPaletteWatch(SDL_Palette * palette, SDL_PaletteChangedFunc callback, | |
270 void *userdata) | |
271 { | |
272 SDL_PaletteWatch *prev, *watch; | |
273 | |
274 if (!palette) { | |
275 return; | |
276 } | |
277 | |
278 for (prev = NULL, watch = palette->watch; watch; | |
279 prev = watch, watch = watch->next) { | |
280 if (watch->callback == callback && watch->userdata == userdata) { | |
281 if (prev) { | |
282 prev->next = watch->next; | |
283 } else { | |
284 palette->watch = watch->next; | |
285 } | |
286 SDL_free(watch); | |
287 SDL_FreePalette(palette); | |
288 return; | |
289 } | |
290 } | |
291 } | |
292 | |
293 int | |
294 SDL_SetPaletteColors(SDL_Palette * palette, const SDL_Color * colors, | |
295 int firstcolor, int ncolors) | |
296 { | |
297 SDL_PaletteWatch *watch; | |
298 int status = 0; | |
299 | |
300 /* Verify the parameters */ | |
301 if (!palette) { | |
302 return -1; | |
303 } | |
304 if (ncolors > (palette->ncolors - firstcolor)) { | |
305 ncolors = (palette->ncolors - firstcolor); | |
306 status = -1; | |
307 } | |
308 | |
309 if (colors != (palette->colors + firstcolor)) { | |
310 SDL_memcpy(palette->colors + firstcolor, colors, | |
311 ncolors * sizeof(*colors)); | |
312 } | |
313 | |
314 for (watch = palette->watch; watch; watch = watch->next) { | |
315 if (watch->callback(watch->userdata, palette) < 0) { | |
316 status = -1; | |
317 } | |
318 } | |
319 | |
320 return status; | |
321 } | |
322 | |
323 void | |
324 SDL_FreePalette(SDL_Palette * palette) | |
325 { | |
326 if (!palette) { | |
327 return; | |
328 } | |
329 if (--palette->refcount > 0) { | |
330 return; | |
331 } | |
332 if (palette->colors) { | |
333 SDL_free(palette->colors); | |
334 } | |
335 SDL_free(palette); | |
336 } | |
337 | |
218 /* | 338 /* |
219 * Allocate a pixel format structure and fill it according to the given info. | 339 * Allocate a pixel format structure and fill it according to the given info. |
220 */ | 340 */ |
221 SDL_PixelFormat * | 341 SDL_PixelFormat * |
222 SDL_AllocFormat(int bpp, | 342 SDL_AllocFormat(int bpp, |
236 | 356 |
237 /* Set up the format */ | 357 /* Set up the format */ |
238 format->BitsPerPixel = bpp; | 358 format->BitsPerPixel = bpp; |
239 format->BytesPerPixel = (bpp + 7) / 8; | 359 format->BytesPerPixel = (bpp + 7) / 8; |
240 if (Rmask || Bmask || Gmask) { /* Packed pixels with custom mask */ | 360 if (Rmask || Bmask || Gmask) { /* Packed pixels with custom mask */ |
241 format->palette = NULL; | |
242 format->Rshift = 0; | 361 format->Rshift = 0; |
243 format->Rloss = 8; | 362 format->Rloss = 8; |
244 if (Rmask) { | 363 if (Rmask) { |
245 for (mask = Rmask; !(mask & 0x01); mask >>= 1) | 364 for (mask = Rmask; !(mask & 0x01); mask >>= 1) |
246 ++format->Rshift; | 365 ++format->Rshift; |
301 format->Rmask = 0; | 420 format->Rmask = 0; |
302 format->Gmask = 0; | 421 format->Gmask = 0; |
303 format->Bmask = 0; | 422 format->Bmask = 0; |
304 format->Amask = 0; | 423 format->Amask = 0; |
305 } | 424 } |
306 if (bpp <= 8) { /* Palettized mode */ | 425 format->palette = NULL; |
307 int ncolors = 1 << bpp; | 426 |
308 #ifdef DEBUG_PALETTE | |
309 fprintf(stderr, "bpp=%d ncolors=%d\n", bpp, ncolors); | |
310 #endif | |
311 format->palette = (SDL_Palette *) SDL_malloc(sizeof(SDL_Palette)); | |
312 if (format->palette == NULL) { | |
313 SDL_FreeFormat(format); | |
314 SDL_OutOfMemory(); | |
315 return (NULL); | |
316 } | |
317 (format->palette)->ncolors = ncolors; | |
318 (format->palette)->colors = (SDL_Color *) SDL_malloc((format-> | |
319 palette)-> | |
320 ncolors * | |
321 sizeof | |
322 (SDL_Color)); | |
323 if ((format->palette)->colors == NULL) { | |
324 SDL_FreeFormat(format); | |
325 SDL_OutOfMemory(); | |
326 return (NULL); | |
327 } | |
328 if (Rmask || Bmask || Gmask) { | |
329 /* create palette according to masks */ | |
330 int i; | |
331 int Rm = 0, Gm = 0, Bm = 0; | |
332 int Rw = 0, Gw = 0, Bw = 0; | |
333 #ifdef ENABLE_PALETTE_ALPHA | |
334 int Am = 0, Aw = 0; | |
335 #endif | |
336 if (Rmask) { | |
337 Rw = 8 - format->Rloss; | |
338 for (i = format->Rloss; i > 0; i -= Rw) | |
339 Rm |= 1 << i; | |
340 } | |
341 #ifdef DEBUG_PALETTE | |
342 fprintf(stderr, "Rw=%d Rm=0x%02X\n", Rw, Rm); | |
343 #endif | |
344 if (Gmask) { | |
345 Gw = 8 - format->Gloss; | |
346 for (i = format->Gloss; i > 0; i -= Gw) | |
347 Gm |= 1 << i; | |
348 } | |
349 #ifdef DEBUG_PALETTE | |
350 fprintf(stderr, "Gw=%d Gm=0x%02X\n", Gw, Gm); | |
351 #endif | |
352 if (Bmask) { | |
353 Bw = 8 - format->Bloss; | |
354 for (i = format->Bloss; i > 0; i -= Bw) | |
355 Bm |= 1 << i; | |
356 } | |
357 #ifdef DEBUG_PALETTE | |
358 fprintf(stderr, "Bw=%d Bm=0x%02X\n", Bw, Bm); | |
359 #endif | |
360 #ifdef ENABLE_PALETTE_ALPHA | |
361 if (Amask) { | |
362 Aw = 8 - format->Aloss; | |
363 for (i = format->Aloss; i > 0; i -= Aw) | |
364 Am |= 1 << i; | |
365 } | |
366 # ifdef DEBUG_PALETTE | |
367 fprintf(stderr, "Aw=%d Am=0x%02X\n", Aw, Am); | |
368 # endif | |
369 #endif | |
370 for (i = 0; i < ncolors; ++i) { | |
371 int r, g, b; | |
372 r = (i & Rmask) >> format->Rshift; | |
373 r = (r << format->Rloss) | ((r * Rm) >> Rw); | |
374 format->palette->colors[i].r = r; | |
375 | |
376 g = (i & Gmask) >> format->Gshift; | |
377 g = (g << format->Gloss) | ((g * Gm) >> Gw); | |
378 format->palette->colors[i].g = g; | |
379 | |
380 b = (i & Bmask) >> format->Bshift; | |
381 b = (b << format->Bloss) | ((b * Bm) >> Bw); | |
382 format->palette->colors[i].b = b; | |
383 | |
384 #ifdef ENABLE_PALETTE_ALPHA | |
385 a = (i & Amask) >> format->Ashift; | |
386 a = (a << format->Aloss) | ((a * Am) >> Aw); | |
387 format->palette->colors[i].unused = a; | |
388 #else | |
389 format->palette->colors[i].unused = SDL_ALPHA_OPAQUE; | |
390 #endif | |
391 } | |
392 } else if (ncolors == 2) { | |
393 /* Create a black and white bitmap palette */ | |
394 format->palette->colors[0].r = 0xFF; | |
395 format->palette->colors[0].g = 0xFF; | |
396 format->palette->colors[0].b = 0xFF; | |
397 format->palette->colors[1].r = 0x00; | |
398 format->palette->colors[1].g = 0x00; | |
399 format->palette->colors[1].b = 0x00; | |
400 } else { | |
401 /* Create an empty palette */ | |
402 SDL_memset((format->palette)->colors, 0xFF, | |
403 (format->palette)->ncolors * sizeof(SDL_Color)); | |
404 } | |
405 } | |
406 return (format); | 427 return (format); |
407 } | |
408 | |
409 SDL_PixelFormat * | |
410 SDL_ReallocFormat(SDL_Surface * surface, int bpp, | |
411 Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) | |
412 { | |
413 if (surface->format) { | |
414 SDL_FreeFormat(surface->format); | |
415 SDL_FormatChanged(surface); | |
416 } | |
417 surface->format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); | |
418 return surface->format; | |
419 } | 428 } |
420 | 429 |
421 /* | 430 /* |
422 * Change any previous mappings from/to the new surface format | 431 * Change any previous mappings from/to the new surface format |
423 */ | 432 */ |
437 * Free a previously allocated format structure | 446 * Free a previously allocated format structure |
438 */ | 447 */ |
439 void | 448 void |
440 SDL_FreeFormat(SDL_PixelFormat * format) | 449 SDL_FreeFormat(SDL_PixelFormat * format) |
441 { | 450 { |
442 if (format) { | 451 if (!format) { |
443 if (format->palette) { | 452 return; |
444 if (format->palette->colors) { | 453 } |
445 SDL_free(format->palette->colors); | 454 SDL_free(format); |
446 } | |
447 SDL_free(format->palette); | |
448 } | |
449 SDL_free(format); | |
450 } | |
451 } | 455 } |
452 | 456 |
453 /* | 457 /* |
454 * Calculate an 8-bit (3 red, 3 green, 2 blue) dithered palette of colors | 458 * Calculate an 8-bit (3 red, 3 green, 2 blue) dithered palette of colors |
455 */ | 459 */ |
693 /* Generate a 256 color dither palette */ | 697 /* Generate a 256 color dither palette */ |
694 SDL_Palette dithered; | 698 SDL_Palette dithered; |
695 SDL_Color colors[256]; | 699 SDL_Color colors[256]; |
696 SDL_Palette *pal = dst->palette; | 700 SDL_Palette *pal = dst->palette; |
697 | 701 |
698 /* SDL_DitherColors does not initialize the 'unused' component of colors, | |
699 but Map1to1 compares it against pal, so we should initialize it. */ | |
700 SDL_memset(colors, 0xFF, sizeof(colors)); | |
701 | |
702 dithered.ncolors = 256; | 702 dithered.ncolors = 256; |
703 SDL_DitherColors(colors, 8); | 703 SDL_DitherColors(colors, 8); |
704 dithered.colors = colors; | 704 dithered.colors = colors; |
705 return (Map1to1(&dithered, pal, identical)); | 705 return (Map1to1(&dithered, pal, identical)); |
706 } | 706 } |
766 switch (srcfmt->BytesPerPixel) { | 766 switch (srcfmt->BytesPerPixel) { |
767 case 1: | 767 case 1: |
768 switch (dstfmt->BytesPerPixel) { | 768 switch (dstfmt->BytesPerPixel) { |
769 case 1: | 769 case 1: |
770 /* Palette --> Palette */ | 770 /* Palette --> Palette */ |
771 /* If both SDL_HWSURFACE, assume have same palette */ | 771 map->table = |
772 if (((src->flags & SDL_HWSURFACE) == SDL_HWSURFACE) && | 772 Map1to1(srcfmt->palette, dstfmt->palette, &map->identity); |
773 ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE)) { | |
774 map->identity = 1; | |
775 } else { | |
776 map->table = Map1to1(srcfmt->palette, | |
777 dstfmt->palette, &map->identity); | |
778 } | |
779 if (!map->identity) { | 773 if (!map->identity) { |
780 if (map->table == NULL) { | 774 if (map->table == NULL) { |
781 return (-1); | 775 return (-1); |
782 } | 776 } |
783 } | 777 } |