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 //