Ejemplo n.º 1
0
static size_t rgb_info(const ss_t *rgb, const struct RGB_Info *ri)
{
	if (rgb && ri) {
		const size_t ss = ss_size(rgb), ps = ri->bpp / 8;
		size_t cmax = ri->bpp == 32 ? 0xffffffff :
					      0xffffffff &
					      ((1 << ri->bpp) - 1),
		       uqp = 0, i;
		const char *p = ss_get_buffer_r(rgb);
		sb_t *bs = sb_alloc(0);
		sb_eval(&bs, cmax);
		switch (ps) {
		case 4: RGB_COUNT_LOOP(i, p, ss, ps, bs, cmax, uqp); break;
		case 3: RGB_COUNT_LOOP(i, p, ss, ps, bs, cmax, uqp); break;
		case 2: RGB_COUNT_LOOP(i, p, ss, ps, bs, cmax, uqp); break;
		case 1: RGB_COUNT_LOOP(i, p, ss, ps, bs, cmax, uqp); break;
		default:
			break;
		}
		unsigned pixels = (unsigned)(ri->width * ri->height);
		unsigned l = (uqp * 100) / pixels,
			 r = ((uqp * 10000) / pixels) % 100;
		printf("%ix%i %i bpp, %i chn; %u px; %u unique px"
		       " (%u.%u%%)", (int)ri->width, (int)ri->height,
		       (int)ri->bpp, (int)ri->chn, pixels,
		       (unsigned)uqp, l, r);
		if (ps == 3 || ps == 4) {
			size_t ur, ug, ub, ua, urg, ugb, urb;
			RGBC_COUNT_LOOP(i, p, ss, ps, bs, 0, ur);
			RGBC_COUNT_LOOP(i, p, ss, ps, bs, 0, ug);
			RGBC_COUNT_LOOP(i, p, ss, ps, bs, 0, ub);
			RGBC2_COUNT_LOOP(i, p, ss, ps, bs, 0, urg);
			RGBC2_COUNT_LOOP(i, p, ss, ps, bs, 1, ugb);
			RGBC2_COUNT_LOOP(i, p, ss, ps, bs, 2, urb);
			if (ps == 4) {
				RGBC_COUNT_LOOP(i, p, ss, ps, bs, 0, ua);
			} else {
				ua = 0;
			}
			printf("; %u ur; %u ug; %u ub; %u urg; %u ugb; %u urb;"
			       " %u ua", (unsigned)ur, (unsigned)ug,
			       (unsigned)ub, (unsigned)urg, (unsigned)ugb,
			       (unsigned)urb, (unsigned)ua);
		}
		printf("\n");
	} else {
		fprintf(stderr, "Error: no pixel data\n");
	}
	return ss_size(rgb);
}
Ejemplo n.º 2
0
int main(int argc, const char **argv)
{
	if (argc < 3)
		return syntax_error(argv, 5);
	int csize = atoi(argv[1]), climit0 = atoi(argv[2]);
	if (csize < 1 || csize > 4)
		return syntax_error(argv, 6);
	if (climit0 < 0)
		return syntax_error(argv, 7);
	int exit_code = 0;
	size_t count = 0;
	size_t cmax = csize == 4 ? 0xffffffff :
				   0xffffffff & ((1 << (csize * 8)) - 1);
	size_t climit = climit0 ? S_MIN((size_t)climit0, cmax) : cmax;
#ifdef COUNTER_USE_BITSET
	#define COUNTER_SET(val) sb_set(&bs, val)
	#define COUNTER_POPCOUNT sb_popcount(bs)
	sb_t *bs = sb_alloc(0);
	sb_eval(&bs, cmax);
#else
	#define COUNTER_SET(val) sm_uu32_insert(&m, val, 1)
	#define COUNTER_POPCOUNT sm_size(m)
	sm_t *m = sm_alloc(SM_U32U32, 0);
#endif
	unsigned char buf[3 * 4 * 128];
	int i;
	ssize_t l;
	for (;;) {
		l = read(0, buf, sizeof(buf));
		l = (l / csize) * csize;
		if (l <= 0)
			break;
		#define CNTLOOP(inc, val)			\
			for (i = 0; i < l; i += inc) {		\
				COUNTER_SET(val);		\
				count++;			\
				if (COUNTER_POPCOUNT >= climit)	\
					goto done;		\
			}
		switch (csize) {
		case 1:	CNTLOOP(1, buf[i]);
			break;
		case 2:	CNTLOOP(2, (size_t)(buf[i] << 8 | buf[i + 1]));
			break;
		case 3:	CNTLOOP(3, (size_t)(buf[i] << 16 | buf[i + 1] << 8 | buf[i + 2]));
			break;
		case 4:	CNTLOOP(4, (size_t)buf[i] << 24 |
				   (size_t)buf[i + 1] << 16 |
				   (size_t)buf[i + 2] << 8 |
				   (size_t)buf[i + 3]);
			break;
		default:
			goto done;
		}
		#undef CNTLOOP
	}
done:
	printf(FMT_ZU ", " FMT_ZU, count, COUNTER_POPCOUNT);
#ifdef COUNTER_USE_BITSET
	sb_free(&bs);
#else
	sm_free(&m);
#endif
	return exit_code;
}