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;