Mercurial > hg > dmlib
comparison tools/libgfx.c @ 1904:5930ff7879b5
Cleanup IFF writer a bit.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 26 Jun 2018 13:22:20 +0300 |
parents | 8ad98bc7402c |
children | 425259977bc5 |
comparison
equal
deleted
inserted
replaced
1903:8ad98bc7402c | 1904:5930ff7879b5 |
---|---|
2042 else | 2042 else |
2043 return dmf_write_str(fp, buf, bufLen); | 2043 return dmf_write_str(fp, buf, bufLen); |
2044 } | 2044 } |
2045 | 2045 |
2046 | 2046 |
2047 int dmEncodeILBMBody(DMResource *fp, DMIFF *iff, const DMImage *img) | |
2048 { | |
2049 Uint8 *buf; | |
2050 size_t bufLen; | |
2051 int res = DMERR_OK; | |
2052 const int nplanes = iff->bmhd.nplanes; | |
2053 | |
2054 // Allocate planar encoding buffer | |
2055 bufLen = ((img->width + 15) / 16) * 2; | |
2056 if ((buf = dmMalloc(bufLen)) == NULL) | |
2057 return DMERR_MALLOC; | |
2058 | |
2059 dmMsg(2, "IFF: plane row size %d bytes.\n", bufLen); | |
2060 | |
2061 // Encode the chunk | |
2062 for (int yc = 0; yc < img->height; yc++) | |
2063 { | |
2064 const Uint8 *sp = img->data + (yc * img->pitch); | |
2065 | |
2066 for (int plane = 0; plane < nplanes; plane++) | |
2067 { | |
2068 // Encode bitplane | |
2069 dmMemset(buf, 0, bufLen); | |
2070 | |
2071 for (int xc = 0; xc < img->width; xc++) | |
2072 buf[xc / 8] |= ((sp[xc] >> plane) & 1) << (7 - (xc & 7)); | |
2073 | |
2074 // Compress / write data | |
2075 if (!dmIFFWriteOneRow(fp, iff, buf, bufLen)) | |
2076 { | |
2077 res = dmError(DMERR_FWRITE, | |
2078 "IFF: Error in writing image plane #%d @ %d.\n", | |
2079 plane, yc); | |
2080 goto error; | |
2081 } | |
2082 } | |
2083 | |
2084 // Write mask data, if any | |
2085 if (iff->bmhd.masking == IFF_MASK_HAS_MASK) | |
2086 { | |
2087 dmMemset(buf, 0, bufLen); | |
2088 | |
2089 for (int xc = 0; xc < img->width; xc++) | |
2090 buf[xc / 8] |= (sp[xc] == img->ctransp) << (7 - (xc & 7)); | |
2091 | |
2092 if (!dmIFFWriteOneRow(fp, iff, buf, bufLen)) | |
2093 { | |
2094 res = dmError(DMERR_FWRITE, | |
2095 "IFF: Error in writing mask plane.\n"); | |
2096 goto error; | |
2097 } | |
2098 } | |
2099 } | |
2100 | |
2101 error: | |
2102 dmFree(buf); | |
2103 return res; | |
2104 } | |
2105 | |
2106 | |
2107 int dmEncodePBMBody(DMResource *fp, DMIFF *iff, const DMImage *img) | |
2108 { | |
2109 for (int yc = 0; yc < img->height; yc++) | |
2110 { | |
2111 if (!dmIFFWriteOneRow(fp, iff, img->data + (yc * img->pitch), img->width)) | |
2112 { | |
2113 return dmError(DMERR_FWRITE, | |
2114 "IFF: Error writing PBM image row #%d.\n", yc); | |
2115 } | |
2116 } | |
2117 | |
2118 return DMERR_OK; | |
2119 } | |
2120 | |
2121 | |
2122 int dmWriteIFFImage(DMResource *fp, const DMImage *img, const DMImageConvSpec *spec) | 2047 int dmWriteIFFImage(DMResource *fp, const DMImage *img, const DMImageConvSpec *spec) |
2123 { | 2048 { |
2124 Uint32 idsig; | 2049 Uint32 idsig; |
2125 DMIFF iff; | 2050 DMIFF iff; |
2051 Uint8 *buf = NULL; | |
2052 size_t bufLen; | |
2126 int res = DMERR_OK; | 2053 int res = DMERR_OK; |
2127 | 2054 |
2128 // XXX: Non-paletted ILBM not supported! | 2055 // XXX: Non-paletted ILBM not supported! |
2129 if (!spec->paletted) | 2056 if (!spec->paletted) |
2130 { | 2057 { |
2133 } | 2060 } |
2134 | 2061 |
2135 // Setup headers | 2062 // Setup headers |
2136 iff.bmhd.x = 0; | 2063 iff.bmhd.x = 0; |
2137 iff.bmhd.y = 0; | 2064 iff.bmhd.y = 0; |
2138 iff.bmhd.w = img->width; | 2065 iff.bmhd.w = img->width * spec->scaleX; |
2139 iff.bmhd.h = img->height; | 2066 iff.bmhd.h = img->height * spec->scaleY; |
2140 iff.bmhd.pagew = img->width; | 2067 iff.bmhd.pagew = img->width * spec->scaleX; |
2141 iff.bmhd.pageh = img->height; | 2068 iff.bmhd.pageh = img->height * spec->scaleY; |
2142 iff.bmhd.pad1 = 0; | 2069 iff.bmhd.pad1 = 0; |
2143 iff.bmhd.xasp = 1; // XXX TODO: compute the xasp/yasp from the img->aspect | 2070 iff.bmhd.xasp = 1; // XXX TODO: compute the xasp/yasp from the img->aspect |
2144 iff.bmhd.yasp = 1; | 2071 iff.bmhd.yasp = 1; |
2145 | 2072 |
2146 iff.camg = 0; // XXX TODO: when/if HAM support | 2073 iff.camg = 0; // XXX TODO: when/if HAM support |
2237 // Encode the body | 2164 // Encode the body |
2238 // | 2165 // |
2239 if ((res = dmWriteIFFChunkHdr(fp, &iff.chBODY, IFF_ID_BODY)) != DMERR_OK) | 2166 if ((res = dmWriteIFFChunkHdr(fp, &iff.chBODY, IFF_ID_BODY)) != DMERR_OK) |
2240 goto out; | 2167 goto out; |
2241 | 2168 |
2169 | |
2170 // Allocate encoding buffer | |
2242 if (spec->planar) | 2171 if (spec->planar) |
2243 { | 2172 bufLen = (((img->width * spec->scaleX) + 15) / 16) * 2; |
2244 if ((res = dmEncodeILBMBody(fp, &iff, img)) != DMERR_OK) | |
2245 goto out; | |
2246 } | |
2247 else | 2173 else |
2248 { | 2174 bufLen = img->width * spec->scaleX; |
2249 if ((res = dmEncodePBMBody(fp, &iff, img)) != DMERR_OK) | 2175 |
2250 goto out; | 2176 dmMsg(2, "IFF: Line/plane row size %d bytes.\n", bufLen); |
2177 | |
2178 if ((buf = dmMalloc(bufLen)) == NULL) | |
2179 return DMERR_MALLOC; | |
2180 | |
2181 // Encode the body | |
2182 for (int yc = 0; yc < img->height; yc++) | |
2183 for (int yscale = 0; yscale < spec->scaleY; yscale++) | |
2184 { | |
2185 const Uint8 *sp = img->data + (yc * img->pitch); | |
2186 | |
2187 if (spec->planar) | |
2188 { | |
2189 for (int plane = 0; plane < spec->nplanes; plane++) | |
2190 { | |
2191 // Encode bitplane | |
2192 dmMemset(buf, 0, bufLen); | |
2193 | |
2194 for (int xc = 0; xc < img->width * spec->scaleX; xc++) | |
2195 buf[xc / 8] |= ((sp[xc / spec->scaleX] >> plane) & 1) << (7 - (xc & 7)); | |
2196 | |
2197 // Compress / write data | |
2198 if (!dmIFFWriteOneRow(fp, &iff, buf, bufLen)) | |
2199 { | |
2200 res = dmError(DMERR_FWRITE, | |
2201 "IFF: Error writing image plane #%d @ %d.\n", | |
2202 plane, yc); | |
2203 goto out; | |
2204 } | |
2205 } | |
2206 | |
2207 // Write mask data, if any | |
2208 if (iff.bmhd.masking == IFF_MASK_HAS_MASK) | |
2209 { | |
2210 dmMemset(buf, 0, bufLen); | |
2211 | |
2212 for (int xc = 0; xc < img->width * spec->scaleX; xc++) | |
2213 buf[xc / 8] |= (sp[xc / spec->scaleX] == img->ctransp) << (7 - (xc & 7)); | |
2214 | |
2215 if (!dmIFFWriteOneRow(fp, &iff, buf, bufLen)) | |
2216 { | |
2217 res = dmError(DMERR_FWRITE, | |
2218 "IFF: Error writing mask plane %d.\n", yc); | |
2219 goto out; | |
2220 } | |
2221 } | |
2222 } | |
2223 else | |
2224 { | |
2225 for (int xc = 0; xc < img->width * spec->scaleX; xc++) | |
2226 buf[xc] = sp[xc / spec->scaleX]; | |
2227 | |
2228 if (!dmIFFWriteOneRow(fp, &iff, buf, bufLen)) | |
2229 { | |
2230 res = dmError(DMERR_FWRITE, | |
2231 "IFF: Error writing PBM image row #%d.\n", yc); | |
2232 goto out; | |
2233 } | |
2234 } | |
2251 } | 2235 } |
2252 | 2236 |
2253 if ((res = dmWriteIFFChunkFinish(fp, &iff.chBODY)) != DMERR_OK) | 2237 if ((res = dmWriteIFFChunkFinish(fp, &iff.chBODY)) != DMERR_OK) |
2254 goto out; | 2238 goto out; |
2255 | 2239 |
2256 // Finish the FORM chunk | 2240 // Finish the FORM chunk |
2257 if ((res = dmWriteIFFChunkFinish(fp, &iff.chFORM)) != DMERR_OK) | 2241 if ((res = dmWriteIFFChunkFinish(fp, &iff.chFORM)) != DMERR_OK) |
2258 goto out; | 2242 goto out; |
2259 | 2243 |
2260 out: | 2244 out: |
2245 dmFree(buf); | |
2261 return res; | 2246 return res; |
2262 } | 2247 } |
2263 | 2248 |
2264 | 2249 |
2265 // | 2250 // |