Ejemplo n.º 1
0
static size_t ppm2rgb(ss_t **rgb, struct RGB_Info *ri, const ss_t *ppm)
{
	RETURN_IF(!ppm || !ri, 0);
	const char *p = ss_get_buffer_r(ppm);
	size_t ps = ss_size(ppm);
	ri->chn = p[1] == '5' ? 1 : p[1] == '6' ? 3 : 0;
	RETURN_IF(ps < 16 || p[0] != 'P' || !ri->chn, 0);
	size_t off = 2, nf = 0, nl, nl2, i = 0;
	int f[PPM_NFIELDS];
	for (; i != S_NPOS && nf < PPM_NFIELDS && off < ps; off = nl + 1) {
		nl = ss_findc(ppm, off, '\n');
		if (nl == S_NPOS)
			break;
		nl2 = ss_findrc(ppm, off, nl, '#'); /* skip comments */
		nl2 = nl2 == S_NPOS ? nl : nl2;
		for (i = off; i < nl2;) { /* get fields */
			i = ss_findrbm(ppm, i, nl2, 0x30, 0xc0); /* digits */
			if (i == S_NPOS)
				break;
			f[nf++] = atoi(p + i);
			if (nf == PPM_NFIELDS)
				break;
			i = ss_findrb(ppm, i + 1, nl2);
		}
	}
	RETURN_IF(nf != PPM_NFIELDS, 0);
	ri->bpp = ri->chn * (f[2] <= 255 ? 1 : f[2] <= 65535 ? 2 : 0) * 8;
	set_rgbi(ri, f[0], f[1], ri->bpp, ri->chn);
	RETURN_IF(!valid_rgbi(ri), 0);
	ss_cpy_cn(rgb, p + off, ps - off); /* Copy pixel data */
	return ss_size(*rgb);
}
Ejemplo n.º 2
0
static size_t tga2rgb(ss_t **rgb, struct RGB_Info *ri, const ss_t *tga)
{
	const char *t = ss_get_buffer_r(tga);
	const size_t ts = ss_size(tga);
	RETURN_IF(ts < TGA_RGBHDR || !valid_tga(t), 0);
	set_rgbi(ri, S_LD_LE_U16(t + TGA_W), S_LD_LE_U16(t + TGA_H),
		 t[TGA_BPP], t[TGA_TYPE] == TGA_RAW_GRAY ? 1 : t[TGA_BPP]/8);
	RETURN_IF(!valid_rgbi(ri), 0);
	size_t rgb_bytes = ri->row_size * ri->height;
	RETURN_IF(ts < rgb_bytes + TGA_RGBHDR, 0);
	RETURN_IF(ss_reserve(rgb, rgb_bytes) < rgb_bytes, 0);
	if ((t[TGA_DESC] & TGA_TOP_LEFT) != 0) {
		if (ri->chn == 1)
			ss_cpy_cn(rgb, t + TGA_RGBHDR, rgb_bytes);
		else
			tga_rgb_swap(ri->bpp, rgb_bytes,
				     ss_get_buffer_r(tga) + TGA_RGBHDR,
				     ss_get_buffer(*rgb));
	} else {
		ss_set_size(*rgb, 0);
		ssize_t i = (ssize_t)(ri->height - 1) * ri->row_size;
		for (; i >= 0; i -= ri->row_size)
			if (ri->chn == 1)
				ss_cat_cn(rgb, t + TGA_RGBHDR + i,
					  ri->row_size);
			else
				tga_rgb_swap(ri->bpp, ri->row_size,
					     t + TGA_RGBHDR + i,
					     ss_get_buffer(*rgb) + i);
	}
	ss_set_size(*rgb, rgb_bytes);
	return rgb_bytes;
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
ss_t *ss_dup_cn(const char *src, const size_t src_size)
{
	ss_t *s = NULL;
	return ss_cpy_cn(&s, src, src_size);
}