static size_t rgb2ppm(ss_t **ppm, const ss_t *rgb, const struct RGB_Info *ri) { RETURN_IF(!ppm || !rgb || !valid_rgbi_for_ppm(ri), 0); int colors_per_channel = (1 << (ri->bpp / ri->chn)) - 1; ss_printf(ppm, 512, "P%i %i %i %i\n", (ri->chn == 1 ? 5 : 6), (int)ri->width, (int)ri->height, colors_per_channel); ss_cat(ppm, rgb); return ss_size(*ppm); }
ss_t *ss_cpy(ss_t **s, const ss_t *src) { ASSERT_RETURN_IF(!s, ss_void); RETURN_IF(*s == src && ss_check(s), *s); /* aliasing, same string */ RETURN_IF(!src, ss_clear(s)); /* BEHAVIOR: empty */ if (*s) ss_clear(s); return ss_cat(s, src); }
static size_t rgb2tga(ss_t **tga, const ss_t *rgb, const struct RGB_Info *ri) { RETURN_IF(!rgb || (!valid_rgbi(ri) && (ri->bpp / ri->chn) != 8), 0); RETURN_IF(ri->chn != 1 && ri->chn != 3 && ri->chn != 4, 0); size_t buf_size = ri->bmp_size + TGA_RGBHDR; RETURN_IF(ss_reserve(tga, buf_size) < buf_size, 0); char *h = ss_get_buffer(*tga); memset(h, 0, TGA_RGBHDR); h[TGA_ID] = TGA_NO_X_INFO; h[TGA_CMAP] = TGA_NO_CMAP; h[TGA_TYPE] = ri->chn == 1 ? TGA_RAW_GRAY : TGA_RAW_RGB; S_ST_LE_U16(h + TGA_W, ri->width); S_ST_LE_U16(h + TGA_H, ri->height); h[TGA_BPP] = ri->bpp; h[TGA_DESC] = TGA_TOP_LEFT; ss_cpy_cn(tga, h, TGA_RGBHDR); if (ri->chn == 1) ss_cat(tga, rgb); else tga_rgb_swap(ri->bpp, ri->bmp_size, ss_get_buffer_r(rgb), ss_get_buffer(*tga) + TGA_RGBHDR); ss_set_size(*tga, buf_size); return ss_size(*tga); }