Mercurial > hg > dmlib
comparison libgfx.c @ 460:0af039b6c0ae
Improve transparent color handling.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sun, 04 Nov 2012 13:57:03 +0200 |
parents | 349a2ff11531 |
children | c7a3aacbd55e |
comparison
equal
deleted
inserted
replaced
459:8ca18222db10 | 460:0af039b6c0ae |
---|---|
46 dmFree(img); | 46 dmFree(img); |
47 } | 47 } |
48 } | 48 } |
49 | 49 |
50 | 50 |
51 BOOL dmPaletteAlloc(DMColor **ppal, int ncolors) | 51 BOOL dmPaletteAlloc(DMColor **ppal, int ncolors, int ctransp) |
52 { | 52 { |
53 int i; | |
54 | |
53 if (ppal == NULL) | 55 if (ppal == NULL) |
54 return FALSE; | 56 return FALSE; |
55 | 57 |
56 return (*ppal = dmCalloc(ncolors, sizeof(DMColor))) != NULL; | 58 // Allocate desired amount of palette |
57 } | 59 if ((*ppal = dmCalloc(ncolors, sizeof(DMColor))) == NULL) |
58 | 60 return FALSE; |
59 | 61 |
60 BOOL dmImageAllocPalette(DMImage *img, int ncolors) | 62 // Set alpha values to max, except for transparent color |
63 for (i = 0; i < ncolors; i++) | |
64 { | |
65 (*ppal)[i].a = (i == ctransp) ? 0 : 255; | |
66 } | |
67 | |
68 return TRUE; | |
69 } | |
70 | |
71 | |
72 BOOL dmImageAllocPalette(DMImage *img, int ncolors, int ctransp) | |
61 { | 73 { |
62 if (img == NULL) | 74 if (img == NULL) |
63 return FALSE; | 75 return FALSE; |
64 | 76 |
65 img->ncolors = ncolors; | 77 img->ncolors = ncolors; |
66 return dmPaletteAlloc(&(img->pal), ncolors); | 78 img->ctransp = ctransp; |
79 return dmPaletteAlloc(&(img->pal), ncolors, ctransp); | |
67 } | 80 } |
68 | 81 |
69 | 82 |
70 int dmImageGetBytesPerPixel(int format) | 83 int dmImageGetBytesPerPixel(int format) |
71 { | 84 { |
138 | 151 |
139 case DM_IFMT_RGBA: | 152 case DM_IFMT_RGBA: |
140 qr = img->pal[c].r; | 153 qr = img->pal[c].r; |
141 qg = img->pal[c].g; | 154 qg = img->pal[c].g; |
142 qb = img->pal[c].b; | 155 qb = img->pal[c].b; |
143 qa = (c == img->ctrans) ? 0 : 255; | 156 qa = img->pal[c].a; |
144 | 157 |
145 for (xscale = 0; xscale < spec->scale; xscale++) | 158 for (xscale = 0; xscale < spec->scale; xscale++) |
146 { | 159 { |
147 *ptr1++ = qr; | 160 *ptr1++ = qr; |
148 *ptr1++ = qg; | 161 *ptr1++ = qg; |
399 fmt, | 412 fmt, |
400 PNG_INTERLACE_NONE, | 413 PNG_INTERLACE_NONE, |
401 PNG_COMPRESSION_TYPE_DEFAULT, | 414 PNG_COMPRESSION_TYPE_DEFAULT, |
402 PNG_FILTER_TYPE_DEFAULT); | 415 PNG_FILTER_TYPE_DEFAULT); |
403 | 416 |
417 dmMsg(2, "PNG: %d x %d, depth=%d, type=%d\n", | |
418 img->width * spec->scale, | |
419 img->height * spec->scale, | |
420 8, fmt); | |
421 | |
404 // Palette | 422 // Palette |
405 if (spec->format == DM_IFMT_PALETTE) | 423 if (spec->format == DM_IFMT_PALETTE) |
406 { | 424 { |
407 int i; | 425 int i; |
408 | 426 |
421 palette[i].red = img->pal[i].r; | 439 palette[i].red = img->pal[i].r; |
422 palette[i].green = img->pal[i].g; | 440 palette[i].green = img->pal[i].g; |
423 palette[i].blue = img->pal[i].b; | 441 palette[i].blue = img->pal[i].b; |
424 } | 442 } |
425 | 443 |
426 png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH); | 444 png_set_PLTE(png_ptr, info_ptr, palette, img->ncolors); |
427 } | 445 } |
428 | 446 |
429 // png_set_gAMA(png_ptr, info_ptr, 2.2); | 447 // png_set_gAMA(png_ptr, info_ptr, 2.2); |
430 | 448 |
431 png_write_info(png_ptr, info_ptr); | 449 png_write_info(png_ptr, info_ptr); |
470 { | 488 { |
471 png_structp png_ptr = NULL; | 489 png_structp png_ptr = NULL; |
472 png_infop info_ptr = NULL; | 490 png_infop info_ptr = NULL; |
473 png_colorp palette = NULL; | 491 png_colorp palette = NULL; |
474 png_bytep *row_pointers = NULL; | 492 png_bytep *row_pointers = NULL; |
493 png_bytep trans = NULL; | |
475 png_uint_32 width, height; | 494 png_uint_32 width, height; |
476 int i, bit_depth, color_type, ncolors; | 495 int i, bit_depth, color_type, ncolors, ntrans; |
477 int res = DMERR_OK; | 496 int res = DMERR_OK; |
478 DMImage *img; | 497 DMImage *img; |
479 | 498 |
480 // Create PNG structures | 499 // Create PNG structures |
481 png_ptr = png_create_read_struct( | 500 png_ptr = png_create_read_struct( |
564 png_read_image(png_ptr, row_pointers); | 583 png_read_image(png_ptr, row_pointers); |
565 | 584 |
566 png_read_end(png_ptr, NULL); | 585 png_read_end(png_ptr, NULL); |
567 | 586 |
568 // Create palette | 587 // Create palette |
569 palette = png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH * sizeof(png_color)); | |
570 if (palette == NULL) | |
571 { | |
572 dmError("PNG: Could not allocate palette structure."); | |
573 res = DMERR_MALLOC; | |
574 goto error; | |
575 } | |
576 | |
577 switch (color_type) | 588 switch (color_type) |
578 { | 589 { |
579 case PNG_COLOR_TYPE_GRAY: | 590 case PNG_COLOR_TYPE_GRAY: |
580 ncolors = 256; | 591 ncolors = 256; |
581 dmMsg(2, "PNG: Generating %d color grayscale palette.\n", ncolors); | 592 dmMsg(2, "PNG: Generating %d color grayscale palette.\n", ncolors); |
582 | 593 |
583 if (!dmImageAllocPalette(img, ncolors)) | 594 if (!dmImageAllocPalette(img, ncolors, -1)) |
584 { | 595 { |
585 res = DMERR_MALLOC; | 596 res = DMERR_MALLOC; |
586 goto error; | 597 goto error; |
587 } | 598 } |
588 | 599 |
596 png_get_PLTE(png_ptr, info_ptr, &palette, &ncolors); | 607 png_get_PLTE(png_ptr, info_ptr, &palette, &ncolors); |
597 dmMsg(2, "PNG: Palette of %d colors found.\n", ncolors); | 608 dmMsg(2, "PNG: Palette of %d colors found.\n", ncolors); |
598 if (ncolors <= 0) | 609 if (ncolors <= 0) |
599 goto error; | 610 goto error; |
600 | 611 |
601 if (!dmImageAllocPalette(img, ncolors)) | 612 if (!dmImageAllocPalette(img, ncolors, -1)) |
602 { | 613 { |
603 res = DMERR_MALLOC; | 614 res = DMERR_MALLOC; |
604 goto error; | 615 goto error; |
605 } | 616 } |
606 | 617 |
611 img->pal[i].b = palette[i].blue; | 622 img->pal[i].b = palette[i].blue; |
612 } | 623 } |
613 break; | 624 break; |
614 } | 625 } |
615 | 626 |
627 if (color_type == PNG_COLOR_TYPE_PALETTE || | |
628 color_type == PNG_COLOR_TYPE_GRAY) | |
629 { | |
630 png_get_tRNS(png_ptr, info_ptr, &trans, &ntrans, NULL); | |
631 for (i = 0; i < img->ncolors && i < ntrans; i++) | |
632 { | |
633 img->pal[i].a = trans[i]; | |
634 } | |
635 } | |
636 | |
616 error: | 637 error: |
617 png_free(png_ptr, palette); | 638 // png_free(png_ptr, palette); |
618 | 639 |
619 if (png_ptr && info_ptr) | 640 if (png_ptr && info_ptr) |
620 png_destroy_read_struct(&png_ptr, &info_ptr, NULL); | 641 png_destroy_read_struct(&png_ptr, &info_ptr, NULL); |
621 | 642 |
622 return res; | 643 return res; |
1073 { | 1094 { |
1074 read = TRUE; | 1095 read = TRUE; |
1075 ncolors = 256; | 1096 ncolors = 256; |
1076 } | 1097 } |
1077 | 1098 |
1078 if (!dmImageAllocPalette(img, ncolors)) | 1099 if (!dmImageAllocPalette(img, ncolors, -1)) |
1079 { | 1100 { |
1080 dmError("PCX: Could not allocate palette data!\n"); | 1101 dmError("PCX: Could not allocate palette data!\n"); |
1081 res = DMERR_MALLOC; | 1102 res = DMERR_MALLOC; |
1082 goto error; | 1103 goto error; |
1083 } | 1104 } |
1474 dmMsg(2, "ILBM: Expected %d entries in CMAP.\n", 1 << iff.bmhd.nplanes); | 1495 dmMsg(2, "ILBM: Expected %d entries in CMAP.\n", 1 << iff.bmhd.nplanes); |
1475 | 1496 |
1476 // Read palette | 1497 // Read palette |
1477 if (iff.ncolors > 0) | 1498 if (iff.ncolors > 0) |
1478 { | 1499 { |
1479 if (!dmPaletteAlloc(&iff.pal, iff.ncolors)) | 1500 if (!dmPaletteAlloc(&iff.pal, iff.ncolors, -1)) |
1480 { | 1501 { |
1481 dmError("ILBM: Could not allocate palette data.\n"); | 1502 dmError("ILBM: Could not allocate palette data.\n"); |
1482 return DMERR_MALLOC; | 1503 return DMERR_MALLOC; |
1483 } | 1504 } |
1484 if (!dmReadPaletteData(fp, iff.pal, iff.ncolors)) | 1505 if (!dmReadPaletteData(fp, iff.pal, iff.ncolors)) |