Mercurial > hg > dmlib
comparison src/libgfx.c @ 1286:b812fad6f33e
Work on libgfx.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 18 Aug 2017 15:20:44 +0300 |
parents | e4bda4909d72 |
children | 32051ad352c8 |
comparison
equal
deleted
inserted
replaced
1285:e4bda4909d72 | 1286:b812fad6f33e |
---|---|
28 else | 28 else |
29 return FALSE; | 29 return FALSE; |
30 } | 30 } |
31 | 31 |
32 | 32 |
33 DMImage * dmImageAlloc(int width, int height) | 33 int dmImageGetBytesPerPixel(const int format) |
34 { | |
35 switch (format) | |
36 { | |
37 case DM_IFMT_PALETTE : return 1; | |
38 | |
39 case DM_IFMT_RGB_PLANE : | |
40 case DM_IFMT_RGB : return 3; | |
41 | |
42 case DM_IFMT_RGBA : return 4; | |
43 | |
44 default: return -1; | |
45 } | |
46 } | |
47 | |
48 | |
49 DMImage * dmImageAlloc(const int width, const int height, const int format, const int bpp) | |
34 { | 50 { |
35 DMImage *img = dmMalloc0(sizeof(DMImage)); | 51 DMImage *img = dmMalloc0(sizeof(DMImage)); |
36 if (img == NULL) | 52 if (img == NULL) |
37 return NULL; | 53 return NULL; |
38 | 54 |
39 img->width = width; | 55 img->width = width; |
40 img->height = height; | 56 img->height = height; |
41 img->pitch = width * sizeof(Uint8); | 57 img->format = format; |
42 | 58 img->bpp = (bpp <= 0) ? dmImageGetBytesPerPixel(format) * 8 : bpp; |
59 img->pitch = width * img->bpp; | |
43 img->size = img->pitch * img->height; | 60 img->size = img->pitch * img->height; |
61 img->ctransp = -1; | |
62 | |
44 if ((img->data = dmMalloc(img->size)) == NULL) | 63 if ((img->data = dmMalloc(img->size)) == NULL) |
45 { | 64 { |
46 dmFree(img); | 65 dmFree(img); |
47 return NULL; | 66 return NULL; |
48 } | 67 } |
92 return FALSE; | 111 return FALSE; |
93 | 112 |
94 img->ncolors = ncolors; | 113 img->ncolors = ncolors; |
95 img->ctransp = ctransp; | 114 img->ctransp = ctransp; |
96 return dmPaletteAlloc(&(img->pal), ncolors, ctransp); | 115 return dmPaletteAlloc(&(img->pal), ncolors, ctransp); |
97 } | |
98 | |
99 | |
100 int dmImageGetBytesPerPixel(int format) | |
101 { | |
102 switch (format) | |
103 { | |
104 case DM_IFMT_PALETTE : return 1; | |
105 | |
106 case DM_IFMT_RGB_PLANE : | |
107 case DM_IFMT_RGB : return 3; | |
108 | |
109 case DM_IFMT_RGBA : return 4; | |
110 | |
111 default: return 0; | |
112 } | |
113 } | 116 } |
114 | 117 |
115 | 118 |
116 static BOOL dmReadPaletteData(FILE *fp, DMColor *pal, int ncolors) | 119 static BOOL dmReadPaletteData(FILE *fp, DMColor *pal, int ncolors) |
117 { | 120 { |
156 *ptr2 = ptr1 + rowWidth, | 159 *ptr2 = ptr1 + rowWidth, |
157 *ptr3 = ptr2 + rowWidth; | 160 *ptr3 = ptr2 + rowWidth; |
158 | 161 |
159 for (x = 0; x < img->width; x++) | 162 for (x = 0; x < img->width; x++) |
160 { | 163 { |
161 Uint8 c = img->data[(y * img->pitch) + x], qr, qg, qb, qa; | 164 Uint8 c = img->data[(y * img->pitch) + (x * img->bpp)], qr, qg, qb, qa; |
162 switch (spec->format) | 165 switch (spec->format) |
163 { | 166 { |
164 case DM_IFMT_PALETTE: | 167 case DM_IFMT_PALETTE: |
165 for (xscale = 0; xscale < spec->scaleX; xscale++) | 168 for (xscale = 0; xscale < spec->scaleX; xscale++) |
166 *ptr1++ = c; | 169 *ptr1++ = c; |
582 | 585 |
583 // Allocate image | 586 // Allocate image |
584 dmMsg(3, "PNG: %d x %d, depth=%d, type=%d\n", | 587 dmMsg(3, "PNG: %d x %d, depth=%d, type=%d\n", |
585 width, height, bit_depth, color_type); | 588 width, height, bit_depth, color_type); |
586 | 589 |
587 if ((*pimg = img = dmImageAlloc(width, height)) == NULL) | 590 if ((*pimg = img = dmImageAlloc(width, height, DM_IFMT_PALETTE, bit_depth)) == NULL) |
588 { | 591 { |
589 res = dmError(DMERR_MALLOC, | 592 res = dmError(DMERR_MALLOC, |
590 "PNG: Could not allocate image data.\n"); | 593 "PNG: Could not allocate image data.\n"); |
591 goto error; | 594 goto error; |
592 } | 595 } |
1014 { | 1017 { |
1015 DMImage *img; | 1018 DMImage *img; |
1016 DMPCXData pcx; | 1019 DMPCXData pcx; |
1017 DMPCXHeader hdr; | 1020 DMPCXHeader hdr; |
1018 int res = 0; | 1021 int res = 0; |
1022 BOOL isPaletted; | |
1019 | 1023 |
1020 pcx.buf = NULL; | 1024 pcx.buf = NULL; |
1021 | 1025 |
1022 // Read PCX header | 1026 // Read PCX header |
1023 if (!dm_fread_byte(fp, &hdr.manufacturer) || | 1027 if (!dm_fread_byte(fp, &hdr.manufacturer) || |
1080 } | 1084 } |
1081 | 1085 |
1082 dmMsg(3, "PCX: nplanes=%d, bpp=%d, bpl=%d\n", | 1086 dmMsg(3, "PCX: nplanes=%d, bpp=%d, bpl=%d\n", |
1083 hdr.nplanes, hdr.bitsPerPlane, hdr.bpl); | 1087 hdr.nplanes, hdr.bitsPerPlane, hdr.bpl); |
1084 | 1088 |
1089 isPaletted = (hdr.bitsPerPlane * hdr.nplanes) < 8; | |
1090 if (!isPaletted) | |
1091 { | |
1092 res = dmError(DMERR_NOT_SUPPORTED, | |
1093 "PCX: Non-indexed (truecolour) PCX images not supported for loading.\n"); | |
1094 goto error; | |
1095 } | |
1096 | |
1085 // Allocate image | 1097 // Allocate image |
1086 if ((*pimg = img = dmImageAlloc(hdr.xmax - hdr.xmin + 1, hdr.ymax - hdr.ymin + 1)) == NULL) | 1098 if ((*pimg = img = dmImageAlloc(hdr.xmax - hdr.xmin + 1, hdr.ymax - hdr.ymin + 1, |
1099 isPaletted ? DM_IFMT_PALETTE : DM_IFMT_RGBA, | |
1100 isPaletted ? (hdr.bitsPerPlane * hdr.nplanes) : -1)) == NULL) | |
1087 { | 1101 { |
1088 res = dmError(DMERR_MALLOC, | 1102 res = dmError(DMERR_MALLOC, |
1089 "PCX: Could not allocate image structure.\n"); | 1103 "PCX: Could not allocate image structure.\n"); |
1090 goto error; | 1104 goto error; |
1091 } | 1105 } |
1120 | 1134 |
1121 // Decode bitplanes | 1135 // Decode bitplanes |
1122 switch (hdr.bitsPerPlane) | 1136 switch (hdr.bitsPerPlane) |
1123 { | 1137 { |
1124 case 8: | 1138 case 8: |
1125 for (int nplane = 0; nplane < hdr.nplanes; nplane++) | |
1126 { | 1139 { |
1127 Uint8 *dptr = dp + nplane, | 1140 // Actually bytes and bits per plane per pixel .. |
1128 *sptr = pcx.buf + (hdr.bpl * nplane); | 1141 const int bytesPerPlane = hdr.bitsPerPlane / 8; |
1129 | 1142 |
1130 for (int xc = 0; xc < img->width; xc += hdr.nplanes, dptr += hdr.nplanes, sptr++) | 1143 for (int nplane = 0; nplane < hdr.nplanes; nplane++) |
1131 *dptr = *sptr; | 1144 { |
1145 Uint8 *dptr = dp + (nplane * bytesPerPlane), | |
1146 *sptr = pcx.buf + (hdr.bpl * nplane); | |
1147 | |
1148 memcpy(dptr, sptr, img->width * bytesPerPlane); | |
1149 } | |
1132 } | 1150 } |
1133 break; | 1151 break; |
1134 | 1152 |
1135 /* | 1153 /* |
1136 case 1: | 1154 case 1: |
1153 | 1171 |
1154 dp += img->pitch; | 1172 dp += img->pitch; |
1155 } | 1173 } |
1156 | 1174 |
1157 // Read additional VGA palette, if available | 1175 // Read additional VGA palette, if available |
1176 if (isPaletted) | |
1158 { | 1177 { |
1159 int ncolors; | 1178 int ncolors; |
1160 Uint8 tmpb; | 1179 Uint8 tmpb; |
1161 BOOL read; | 1180 BOOL read; |
1162 | 1181 |
1274 DMIFFChunk chBMHD, chCMAP, chBODY; | 1293 DMIFFChunk chBMHD, chCMAP, chBODY; |
1275 DMIFFBMHD bmhd; | 1294 DMIFFBMHD bmhd; |
1276 Uint32 camg; | 1295 Uint32 camg; |
1277 int ncolors; | 1296 int ncolors; |
1278 DMColor *pal; | 1297 DMColor *pal; |
1279 BOOL paletted, planar; | 1298 BOOL planar; |
1280 } DMIFF; | 1299 } DMIFF; |
1281 | 1300 |
1282 | 1301 |
1283 static BOOL dmReadIFFChunk(FILE *fp, DMIFFChunk *chunk) | 1302 static BOOL dmReadIFFChunk(FILE *fp, DMIFFChunk *chunk) |
1284 { | 1303 { |
1415 int yc, res = DMERR_OK; | 1434 int yc, res = DMERR_OK; |
1416 | 1435 |
1417 *read = 0; | 1436 *read = 0; |
1418 | 1437 |
1419 // Allocate image | 1438 // Allocate image |
1420 if ((*pimg = img = dmImageAlloc(iff->bmhd.w, iff->bmhd.h)) == NULL) | 1439 if ((*pimg = img = dmImageAlloc(iff->bmhd.w, iff->bmhd.h, |
1440 iff->bmhd.nplanes < 8 ? DM_IFMT_PALETTE : DM_IFMT_RGBA, | |
1441 iff->bmhd.nplanes < 8 ? iff->bmhd.nplanes : -1)) == NULL) | |
1421 return DMERR_MALLOC; | 1442 return DMERR_MALLOC; |
1422 | 1443 |
1423 // Allocate planar decoding buffer | 1444 // Allocate planar decoding buffer |
1424 bufLen = ((img->width + 15) / 16) * 2; | 1445 bufLen = ((img->width + 15) / 16) * 2; |
1425 if ((buf = dmMalloc(bufLen)) == NULL) | 1446 if ((buf = dmMalloc(bufLen)) == NULL) |
1492 int yc, res = DMERR_OK; | 1513 int yc, res = DMERR_OK; |
1493 | 1514 |
1494 *read = 0; | 1515 *read = 0; |
1495 | 1516 |
1496 // Allocate image | 1517 // Allocate image |
1497 if ((*pimg = img = dmImageAlloc(iff->bmhd.w, iff->bmhd.h)) == NULL) | 1518 if ((*pimg = img = dmImageAlloc(iff->bmhd.w, iff->bmhd.h, |
1519 iff->bmhd.nplanes < 8 ? DM_IFMT_PALETTE : DM_IFMT_RGBA, | |
1520 iff->bmhd.nplanes < 8 ? iff->bmhd.nplanes : -1)) == NULL) | |
1498 return DMERR_MALLOC; | 1521 return DMERR_MALLOC; |
1499 | 1522 |
1500 // Decode the chunk | 1523 // Decode the chunk |
1501 for (yc = 0; yc < img->height; yc++) | 1524 for (yc = 0; yc < img->height; yc++) |
1502 { | 1525 { |