comparison tools/libgfx.c @ 2093:d17512dbb4ef

Some work on reading >8bpp images.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 28 Feb 2019 12:32:07 +0200
parents 614b161c0aa5
children 4276b8c0fef0
comparison
equal deleted inserted replaced
2092:614b161c0aa5 2093:d17512dbb4ef
128 return NULL; 128 return NULL;
129 129
130 img->width = width; 130 img->width = width;
131 img->height = height; 131 img->height = height;
132 img->format = format; 132 img->format = format;
133 img->bpp = (bpp <= 0) ? dmImageGetBytesPerPixel(format) * 8 : bpp; 133 img->bpp = (bpp <= 0) ? dmImageGetBitsPerPixel(format) : bpp;
134 img->pitch = width * img->bpp; 134 img->pitch = (width * img->bpp) / 8;
135 img->size = img->pitch * img->height; 135 img->size = img->pitch * img->height;
136 img->ctransp = -1; 136 img->ctransp = -1;
137 img->aspect = -1; 137 img->aspect = -1;
138 138
139 if ((img->data = dmMalloc(img->size)) == NULL) 139 if ((img->data = dmMalloc(img->size)) == NULL)
712 png_set_write_fn(png_ptr, fp, dmPNGWriteData, dmPNGWriteFlush); 712 png_set_write_fn(png_ptr, fp, dmPNGWriteData, dmPNGWriteFlush);
713 713
714 // Write PNG header info 714 // Write PNG header info
715 switch (spec->format) 715 switch (spec->format)
716 { 716 {
717 case DM_COLFMT_PALETTE: fmt = PNG_COLOR_TYPE_PALETTE; break; 717 case DM_COLFMT_PALETTE : fmt = PNG_COLOR_TYPE_PALETTE; break;
718 case DM_COLFMT_RGB : fmt = PNG_COLOR_TYPE_RGB; break; 718 case DM_COLFMT_GRAYSCALE : fmt = PNG_COLOR_TYPE_GRAY; break;
719 case DM_COLFMT_RGBA : fmt = PNG_COLOR_TYPE_RGB_ALPHA; break; 719 case DM_COLFMT_RGB : fmt = PNG_COLOR_TYPE_RGB; break;
720 case DM_COLFMT_RGBA : fmt = PNG_COLOR_TYPE_RGB_ALPHA; break;
720 default: 721 default:
721 res = dmError(DMERR_NOT_SUPPORTED, 722 res = dmError(DMERR_NOT_SUPPORTED,
722 "PNG: Unsupported image format %d.\n", 723 "PNG: Unsupported image format %d.\n",
723 spec->format); 724 spec->format);
724 goto error; 725 goto error;
799 png_infop info_ptr = NULL; 800 png_infop info_ptr = NULL;
800 png_colorp palette = NULL; 801 png_colorp palette = NULL;
801 png_bytep *row_pointers = NULL; 802 png_bytep *row_pointers = NULL;
802 png_bytep trans = NULL; 803 png_bytep trans = NULL;
803 png_uint_32 width, height, res_x = 0, res_y = 0; 804 png_uint_32 width, height, res_x = 0, res_y = 0;
804 int i, bit_depth, color_type, ncolors, ntrans, unit_type; 805 int i, itype, bit_depth, color_type, ncolors, ntrans, unit_type;
805 int res = DMERR_OK; 806 int res = DMERR_OK;
806 DMImage *img; 807 DMImage *img;
807 808
808 // Create PNG structures 809 // Create PNG structures
809 png_ptr = png_create_read_struct( 810 png_ptr = png_create_read_struct(
850 } 851 }
851 852
852 switch (color_type) 853 switch (color_type)
853 { 854 {
854 case PNG_COLOR_TYPE_GRAY: 855 case PNG_COLOR_TYPE_GRAY:
855 if (bit_depth < 8)
856 png_set_expand_gray_1_2_4_to_8(png_ptr);
857
858 if (bit_depth > 8) 856 if (bit_depth > 8)
859 { 857 {
860 res = dmError(DMERR_NOT_SUPPORTED, 858 res = dmError(DMERR_NOT_SUPPORTED,
861 "PNG: Unsupported bit depth for grayscale image: %d\n", 859 "PNG: Unsupported bit depth for grayscale image: %d\n",
862 bit_depth); 860 bit_depth);
863 goto error; 861 goto error;
864 } 862 }
863
864 if (bit_depth < 8)
865 png_set_expand_gray_1_2_4_to_8(png_ptr);
866
867 itype = DM_COLFMT_GRAYSCALE;
865 break; 868 break;
866 869
867 case PNG_COLOR_TYPE_PALETTE: 870 case PNG_COLOR_TYPE_PALETTE:
868 png_set_packing(png_ptr); 871 png_set_packing(png_ptr);
872 itype = DM_COLFMT_PALETTE;
873 break;
874
875 case PNG_COLOR_TYPE_RGB:
876 itype = DM_COLFMT_RGB;
877 break;
878
879 case PNG_COLOR_TYPE_RGBA:
880 itype = DM_COLFMT_RGBA;
869 break; 881 break;
870 882
871 default: 883 default:
872 res = dmError(DMERR_NOT_SUPPORTED, 884 res = dmError(DMERR_NOT_SUPPORTED,
873 "PNG: RGB/RGBA images not supported for loading.\n"); 885 "PNG: RGB/RGBA images not supported for loading.\n");
877 // Allocate image 889 // Allocate image
878 dmMsg(2, "PNG: %d x %d, depth=%d, type=%d\n", 890 dmMsg(2, "PNG: %d x %d, depth=%d, type=%d\n",
879 width, height, bit_depth, color_type); 891 width, height, bit_depth, color_type);
880 892
881 if ((*pimg = img = dmImageAlloc(width, height, 893 if ((*pimg = img = dmImageAlloc(width, height,
882 DM_COLFMT_PALETTE, 894 itype,
883 // XXX TODO? When/if we ever handle < 8bit indexed correctly, we can use the actual bpp 895 // XXX TODO? When/if we ever handle < 8bit indexed correctly, we can use the actual bpp
884 -1 /* bit_depth */)) == NULL) 896 -1 /* bit_depth */)) == NULL)
885 { 897 {
886 res = dmError(DMERR_MALLOC, 898 res = dmError(DMERR_MALLOC,
887 "PNG: Could not allocate image data.\n"); 899 "PNG: Could not allocate image data.\n");
906 918
907 png_read_end(png_ptr, NULL); 919 png_read_end(png_ptr, NULL);
908 png_free(png_ptr, row_pointers); 920 png_free(png_ptr, row_pointers);
909 921
910 // Create palette 922 // Create palette
911 switch (color_type) 923 if (color_type == PNG_COLOR_TYPE_PALETTE)
912 { 924 {
913 case PNG_COLOR_TYPE_GRAY: 925 png_get_PLTE(png_ptr, info_ptr, &palette, &ncolors);
914 ncolors = 256; 926 if (ncolors > 0 && palette != NULL)
915 dmMsg(2, "PNG: Generating %d color grayscale palette.\n", ncolors); 927 {
928 dmMsg(2, "PNG: Palette of %d colors found.\n", ncolors);
916 929
917 if (!dmImagePaletteAlloc(img, ncolors, -1)) 930 if (!dmImagePaletteAlloc(img, ncolors, -1))
918 { 931 {
919 res = DMERR_MALLOC; 932 res = DMERR_MALLOC;
920 goto error; 933 goto error;
921 } 934 }
922 935
923 for (i = 0; i < img->ncolors; i++) 936 for (i = 0; i < img->ncolors; i++)
924 { 937 {
925 img->pal[i].r = img->pal[i].g = img->pal[i].b = i; 938 img->pal[i].r = palette[i].red;
926 } 939 img->pal[i].g = palette[i].green;
927 break; 940 img->pal[i].b = palette[i].blue;
928 941 }
929 case PNG_COLOR_TYPE_PALETTE: 942 }
930 png_get_PLTE(png_ptr, info_ptr, &palette, &ncolors); 943
931 dmMsg(2, "PNG: Palette of %d colors found.\n", ncolors);
932 if (ncolors > 0 && palette != NULL)
933 {
934 if (!dmImagePaletteAlloc(img, ncolors, -1))
935 {
936 res = DMERR_MALLOC;
937 goto error;
938 }
939
940 for (i = 0; i < img->ncolors; i++)
941 {
942 img->pal[i].r = palette[i].red;
943 img->pal[i].g = palette[i].green;
944 img->pal[i].b = palette[i].blue;
945 }
946 }
947 break;
948 }
949
950 if (color_type == PNG_COLOR_TYPE_PALETTE ||
951 color_type == PNG_COLOR_TYPE_GRAY)
952 {
953 png_get_tRNS(png_ptr, info_ptr, &trans, &ntrans, NULL); 944 png_get_tRNS(png_ptr, info_ptr, &trans, &ntrans, NULL);
954 if (trans != NULL && ntrans > 0) 945 if (trans != NULL && ntrans > 0)
955 { 946 {
956 dmMsg(2, "PNG: %d transparent colors.\n", ntrans); 947 dmMsg(2, "PNG: %d transparent colors.\n", ntrans);
957 for (i = 0; i < img->ncolors && i < ntrans; i++) 948 for (i = 0; i < img->ncolors && i < ntrans; i++)
1129 // Always force planar for PCX 1120 // Always force planar for PCX
1130 memcpy(&spec, pspec, sizeof(DMImageConvSpec)); 1121 memcpy(&spec, pspec, sizeof(DMImageConvSpec));
1131 spec.planar = TRUE; 1122 spec.planar = TRUE;
1132 1123
1133 // XXX: 24bit PCX does not work yet .. 1124 // XXX: 24bit PCX does not work yet ..
1134 if (spec.format != DM_COLFMT_PALETTE) 1125 if (spec.format != DM_COLFMT_PALETTE &&
1126 spec.format != DM_COLFMT_GRAYSCALE)
1135 { 1127 {
1136 return dmError(DMERR_NOT_SUPPORTED, 1128 return dmError(DMERR_NOT_SUPPORTED,
1137 "24bit PCX not supported yet.\n"); 1129 "24bit PCX not supported yet.\n");
1138 } 1130 }
1139 1131
1148 pcx.header = &hdr; 1140 pcx.header = &hdr;
1149 pcx.fp = fp; 1141 pcx.fp = fp;
1150 1142
1151 // Create PCX header 1143 // Create PCX header
1152 dmMemset(&hdr, 0, sizeof(hdr)); 1144 dmMemset(&hdr, 0, sizeof(hdr));
1153 if (spec.format == DM_COLFMT_PALETTE) 1145 if (spec.format == DM_COLFMT_PALETTE ||
1146 spec.format == DM_COLFMT_GRAYSCALE)
1154 { 1147 {
1155 const int ncolors = img->ncolors > DMPCX_PAL_COLORS ? DMPCX_PAL_COLORS : img->ncolors; 1148 const int ncolors = img->ncolors > DMPCX_PAL_COLORS ? DMPCX_PAL_COLORS : img->ncolors;
1156 for (int i = 0; i < ncolors; i++) 1149 for (int i = 0; i < ncolors; i++)
1157 { 1150 {
1158 hdr.colorMap[i].r = img->pal[i].r; 1151 hdr.colorMap[i].r = img->pal[i].r;
1248 1241
1249 // Write image data 1242 // Write image data
1250 res = dmWriteImageData(img, (void *) &pcx, dmWritePCXRow, &spec); 1243 res = dmWriteImageData(img, (void *) &pcx, dmWritePCXRow, &spec);
1251 1244
1252 // Write VGA palette 1245 // Write VGA palette
1253 if (spec.format == DM_COLFMT_PALETTE) 1246 if (spec.format == DM_COLFMT_PALETTE ||
1247 spec.format == DM_COLFMT_GRAYSCALE)
1254 { 1248 {
1255 int i; 1249 int i;
1256 dmMsg(2, "PCX: Writing palette of %d active entries.\n", img->ncolors); 1250 dmMsg(2, "PCX: Writing palette of %d active entries.\n", img->ncolors);
1257 1251
1258 dmf_write_byte(pcx.fp, 0x0C); 1252 dmf_write_byte(pcx.fp, 0x0C);
1424 goto error; 1418 goto error;
1425 } 1419 }
1426 1420
1427 // Allocate image 1421 // Allocate image
1428 if ((*pimg = img = dmImageAlloc(hdr.xmax - hdr.xmin + 1, hdr.ymax - hdr.ymin + 1, 1422 if ((*pimg = img = dmImageAlloc(hdr.xmax - hdr.xmin + 1, hdr.ymax - hdr.ymin + 1,
1429 isPaletted ? DM_COLFMT_PALETTE : DM_COLFMT_RGBA, 1423 isPaletted ? DM_COLFMT_PALETTE : DM_COLFMT_RGB,
1430 // XXX TODO? When/if we ever handle < 8bit indexed correctly, we can use the actual bpp 1424 // XXX TODO? When/if we ever handle < 8bit indexed correctly, we can use the actual bpp
1431 // isPaletted ? (hdr.bitsPerPlane * hdr.nplanes) : -1 1425 // isPaletted ? (hdr.bitsPerPlane * hdr.nplanes) : -1
1432 -1 1426 -1
1433 )) == NULL) 1427 )) == NULL)
1434 { 1428 {