Mercurial > hg > dmlib
comparison src/libgfx.c @ 1284:28be63226b05
More work on PCX loader.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 18 Aug 2017 03:09:26 +0300 |
parents | 642a0dd98c6e |
children | e4bda4909d72 |
comparison
equal
deleted
inserted
replaced
1283:642a0dd98c6e | 1284:28be63226b05 |
---|---|
837 hdr.nplanes = dmImageGetBytesPerPixel(pcx.format); | 837 hdr.nplanes = dmImageGetBytesPerPixel(pcx.format); |
838 hdr.palInfo = 1; | 838 hdr.palInfo = 1; |
839 hdr.hScreenSize = hdr.hres; | 839 hdr.hScreenSize = hdr.hres; |
840 hdr.vScreenSize = hdr.vres; | 840 hdr.vScreenSize = hdr.vres; |
841 | 841 |
842 res = (img->width * spec->scaleX); | 842 res = img->width * spec->scaleX; |
843 hdr.bpl = res / 2; | 843 hdr.bpl = res / 2; |
844 if (res % 2) hdr.bpl++; | 844 if (res % 2) hdr.bpl++; |
845 hdr.bpl *= 2; | 845 hdr.bpl *= 2; |
846 | 846 |
847 dmMsg(3, "PCX: paletted=%d, nplanes=%d, bpp=%d, bpl=%d\n", | 847 dmMsg(3, "PCX: paletted=%d, nplanes=%d, bpp=%d, bpl=%d\n", |
948 fclose(fp); | 948 fclose(fp); |
949 return res; | 949 return res; |
950 } | 950 } |
951 | 951 |
952 | 952 |
953 static BOOL dmPCXDecodeRLERow(FILE *fp, Uint8 *buf, const size_t bufLen) | 953 static BOOL dmPCXDecodeRLERow(FILE *fp, Uint8 *buf, const size_t bufLen, const int errorMode) |
954 { | 954 { |
955 size_t offs = 0; | 955 size_t offs = 0; |
956 do | 956 do |
957 { | 957 { |
958 int count; | 958 int count; |
961 if (!dm_fread_byte(fp, &data)) | 961 if (!dm_fread_byte(fp, &data)) |
962 return FALSE; | 962 return FALSE; |
963 | 963 |
964 if ((data & 0xC0) == 0xC0) | 964 if ((data & 0xC0) == 0xC0) |
965 { | 965 { |
966 BOOL skip = FALSE; | |
966 count = data & 0x3F; | 967 count = data & 0x3F; |
967 if (!dm_fread_byte(fp, &data)) | 968 if (count == 0) |
969 { | |
970 switch (errorMode) | |
971 { | |
972 case 1: | |
973 // Use as literal | |
974 skip = TRUE; | |
975 count = 1; | |
976 break; | |
977 | |
978 case 2: | |
979 // Ignore completely | |
980 skip = TRUE; | |
981 break; | |
982 | |
983 default: | |
984 // Error out on "invalid" data | |
985 return FALSE; | |
986 } | |
987 } | |
988 | |
989 if (!skip && !dm_fread_byte(fp, &data)) | |
968 return FALSE; | 990 return FALSE; |
969 } | 991 } |
970 else | 992 else |
971 count = 1; | 993 count = 1; |
972 | 994 |
973 while (count-- && offs < bufLen) | 995 while (count-- && offs < bufLen) |
974 buf[offs++] = data; | 996 buf[offs++] = data; |
997 | |
998 // Check for remaining output count, error out if we wish to | |
999 if (count > 0 && errorMode != 0) | |
1000 return FALSE; | |
975 | 1001 |
976 } while (offs < bufLen); | 1002 } while (offs < bufLen); |
977 | 1003 |
978 return TRUE; | 1004 return TRUE; |
979 } | 1005 } |
1075 // Read image data | 1101 // Read image data |
1076 Uint8 *dp = img->data; | 1102 Uint8 *dp = img->data; |
1077 for (int yc = 0; yc < img->height; yc++) | 1103 for (int yc = 0; yc < img->height; yc++) |
1078 { | 1104 { |
1079 // Decode row of RLE'd data | 1105 // Decode row of RLE'd data |
1080 if (!dmPCXDecodeRLERow(fp, pcx.buf, pcx.bufLen)) | 1106 if (!dmPCXDecodeRLERow(fp, pcx.buf, pcx.bufLen, 0)) |
1081 { | 1107 { |
1082 res = dmError(DMERR_INVALID_DATA, | 1108 res = dmError(DMERR_INVALID_DATA, |
1083 "PCX: Error decoding RLE compressed data.\n"); | 1109 "PCX: Error decoding RLE compressed data.\n"); |
1084 goto error; | 1110 goto error; |
1085 } | 1111 } |