Mercurial > hg > dmlib
comparison tools/libgfx.c @ 2050:416af5a842ec
Fixes to the ByteRun1 encoder. Could use some cleanups now, tho.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 03 Dec 2018 19:01:07 +0200 |
parents | a945a5f2fd70 |
children | 6dfbe976d740 |
comparison
equal
deleted
inserted
replaced
2049:a945a5f2fd70 | 2050:416af5a842ec |
---|---|
2046 DMODE_LIT, | 2046 DMODE_LIT, |
2047 DMODE_RLE, | 2047 DMODE_RLE, |
2048 }; | 2048 }; |
2049 | 2049 |
2050 | 2050 |
2051 BOOL dmIFFEncodeByteRun1Flush( | 2051 BOOL dmIFFEncodeByteRun1LIT(DMResource *fp, |
2052 DMResource *fp, const int mode, const BOOL flush, | 2052 const Uint8 *buf, const size_t offs, |
2053 size_t *l_offs, const size_t offs, const Uint8 *buf, | 2053 const size_t count) |
2054 const Uint8 data, unsigned int *r_count) | 2054 { |
2055 { | 2055 if (count <= 0) |
2056 if (mode == DMODE_LIT) | 2056 return TRUE; |
2057 { | 2057 |
2058 size_t l_count = offs - *l_offs; | 2058 Uint8 tmp = count - 1; |
2059 if (l_count > *r_count || flush) | 2059 |
2060 { | 2060 return |
2061 size_t count = l_count - *r_count; | 2061 dmf_write_byte(fp, tmp) && |
2062 Uint8 tmp = count - 1; | 2062 dmf_write_str(fp, buf + offs, count); |
2063 | 2063 } |
2064 if (!dmf_write_byte(fp, tmp) || | 2064 |
2065 !dmf_write_str(fp, buf + *l_offs, count)) | 2065 |
2066 return FALSE; | 2066 BOOL dmIFFEncodeByteRun1RLE(DMResource *fp, |
2067 } | 2067 const Uint8 *buf, const size_t offs, |
2068 (*r_count)++; | 2068 const size_t count) |
2069 } | 2069 { |
2070 else | 2070 if (count <= 0) |
2071 { | 2071 return TRUE; |
2072 if (*r_count > 0) | 2072 |
2073 { | 2073 Uint8 |
2074 unsigned int count = *r_count; | 2074 tmp = ((Uint8) count - 2) ^ 0xff, |
2075 Uint8 tmp = ((Uint8) count - 2) ^ 0xff; | 2075 data = buf[offs]; |
2076 | 2076 |
2077 if (!dmf_write_byte(fp, tmp) || | 2077 return |
2078 !dmf_write_byte(fp, data)) | 2078 dmf_write_byte(fp, tmp) && |
2079 return FALSE; | 2079 dmf_write_byte(fp, data); |
2080 | |
2081 *r_count = 0; | |
2082 } | |
2083 *l_offs = offs; | |
2084 } | |
2085 | |
2086 return TRUE; | |
2087 } | 2080 } |
2088 | 2081 |
2089 | 2082 |
2090 BOOL dmIFFEncodeByteRun1Row(DMResource *fp, const Uint8 *buf, const size_t bufLen) | 2083 BOOL dmIFFEncodeByteRun1Row(DMResource *fp, const Uint8 *buf, const size_t bufLen) |
2091 { | 2084 { |
2092 unsigned int r_count = 0; | |
2093 int prev = -1, mode = DMODE_LIT; | 2085 int prev = -1, mode = DMODE_LIT; |
2094 size_t offs, l_offs = 0; | 2086 size_t offs, l_offs, r_offs; |
2095 | 2087 BOOL ret = TRUE; |
2096 for (offs = 0; offs < bufLen; offs++) | 2088 |
2089 for (offs = l_offs = r_offs = 0; offs < bufLen; offs++) | |
2097 { | 2090 { |
2098 Uint8 data = buf[offs]; | 2091 Uint8 data = buf[offs]; |
2099 int next_mode; | 2092 BOOL flush = FALSE; |
2100 BOOL flush; | 2093 int pmode = mode; |
2101 | 2094 |
2102 if (data == prev) | 2095 if (data == prev) |
2103 { | 2096 { |
2104 r_count++; | 2097 if (mode == DMODE_LIT && |
2105 next_mode = DMODE_RLE; | 2098 offs - r_offs >= 2) |
2099 { | |
2100 ret = dmIFFEncodeByteRun1LIT(fp, buf, l_offs, r_offs - l_offs); | |
2101 mode = DMODE_RLE; | |
2102 } | |
2106 } | 2103 } |
2107 else | 2104 else |
2108 { | 2105 { |
2109 next_mode = DMODE_LIT; | 2106 if (mode != DMODE_LIT) |
2110 } | 2107 { |
2111 | 2108 ret = dmIFFEncodeByteRun1RLE(fp, buf, r_offs, offs - r_offs); |
2112 flush = offs - l_offs >= 126 || r_count >= 126; | 2109 mode = DMODE_LIT; |
2113 if ((next_mode != mode || flush) && | 2110 l_offs = offs; |
2114 !dmIFFEncodeByteRun1Flush(fp, mode, flush, &l_offs, offs, buf, prev, &r_count)) | 2111 } |
2115 return FALSE; | 2112 r_offs = offs; |
2116 | 2113 } |
2117 mode = next_mode; | 2114 |
2115 if (!ret) | |
2116 goto out; | |
2117 | |
2118 // NOTE! RLE and LIT max are both 128, checked against DP2e | |
2119 flush = | |
2120 (pmode == DMODE_RLE && offs - r_offs >= 128) || | |
2121 (pmode == DMODE_LIT && offs - l_offs >= 128); | |
2122 | |
2123 // Check for last byte of input | |
2124 if (offs == bufLen - 1) | |
2125 { | |
2126 offs++; | |
2127 flush = TRUE; | |
2128 pmode = mode; | |
2129 } | |
2130 | |
2131 if (flush) | |
2132 { | |
2133 if (pmode == DMODE_RLE) | |
2134 ret = dmIFFEncodeByteRun1RLE(fp, buf, r_offs, offs - r_offs); | |
2135 else | |
2136 ret = dmIFFEncodeByteRun1LIT(fp, buf, l_offs, offs - l_offs); | |
2137 | |
2138 r_offs = l_offs = offs; | |
2139 mode = DMODE_LIT; | |
2140 | |
2141 if (!ret) | |
2142 goto out; | |
2143 } | |
2144 | |
2118 prev = data; | 2145 prev = data; |
2119 } | 2146 } |
2120 | 2147 |
2121 if (!dmIFFEncodeByteRun1Flush(fp, mode, TRUE, &l_offs, offs, buf, prev, &r_count)) | 2148 out: |
2122 return FALSE; | 2149 return ret; |
2123 | |
2124 return TRUE; | |
2125 } | 2150 } |
2126 | 2151 |
2127 | 2152 |
2128 static BOOL dmIFFWriteOneRow(DMResource *fp, DMIFF *iff, const Uint8 *buf, const size_t bufLen) | 2153 static BOOL dmIFFWriteOneRow(DMResource *fp, DMIFF *iff, const Uint8 *buf, const size_t bufLen) |
2129 { | 2154 { |
2254 } | 2279 } |
2255 | 2280 |
2256 if ((res = dmWriteIFFChunkFinish(fp, &iff.chCMAP)) != DMERR_OK) | 2281 if ((res = dmWriteIFFChunkFinish(fp, &iff.chCMAP)) != DMERR_OK) |
2257 goto out; | 2282 goto out; |
2258 | 2283 |
2284 | |
2259 // | 2285 // |
2260 // Encode the body | 2286 // Encode the body |
2261 // | 2287 // |
2262 if ((res = dmWriteIFFChunkHdr(fp, &iff.chBODY, IFF_ID_BODY)) != DMERR_OK) | 2288 if ((res = dmWriteIFFChunkHdr(fp, &iff.chBODY, IFF_ID_BODY)) != DMERR_OK) |
2263 goto out; | 2289 goto out; |