示例#1
0
static int test_save_PNG(GP_PixelType pixel_type)
{
	GP_Context *ctx;
	int ret;

	ctx = GP_ContextAlloc(100, 100, pixel_type);

	if (ctx == NULL) {
		tst_msg("Failed to allocate context");
		return TST_UNTESTED;
	}

	errno = 0;

	ret = GP_SavePNG(ctx, "/dev/null", NULL);

	if (ret == 0) {
		tst_msg("Saved successfully");
		GP_ContextFree(ctx);
		return TST_SUCCESS;
	}

	switch (errno) {
	case ENOSYS:
		tst_msg("Not Implemented");
		GP_ContextFree(ctx);
		return TST_SKIPPED;
	default:
		tst_msg("Failed and errno is not ENOSYS (%i)", errno);
		GP_ContextFree(ctx);
		return TST_FAILED;
	}
}
示例#2
0
static int test_load_PNG(const char *path)
{
	GP_Context *img;

	errno = 0;

	img = GP_LoadPNG(path, NULL);

	if (img == NULL) {
		switch (errno) {
		case ENOSYS:
			tst_msg("Not Implemented");
			return TST_SKIPPED;
		default:
			tst_msg("Got %s", strerror(errno));
			return TST_FAILED;
		}
	}

	/*
	 * TODO: check correct data.
	 */

	GP_ContextFree(img);

	return TST_SUCCESS;
}
示例#3
0
int main(int argc, char *argv[])
{
	GP_Context *img;
	struct callback_priv priv;
	GP_ProgressCallback callback = {.callback = progress_callback,
	                                .priv = &priv};

	if (argc != 2) {
		fprintf(stderr, "Takes an image as an parameter\n");
		return 1;
	}

	priv.op   = "Loading";
	priv.name = argv[1];

	img = GP_LoadImage(argv[1], &callback);

	if (img == NULL) {
		fprintf(stderr, "Failed to load image '%s':%s\n", argv[1],
		        strerror(errno));
		return 1;
	}

	printf("\n");

	priv.op   = "Saving";
	priv.name = "tmp.gfx";

	if (GP_SaveTmpFile(img, priv.name, &callback)) {
		fprintf(stderr, "Failed to save temp file %s\n", strerror(errno));
		return 1;
	}

	printf("\n");

	GP_ContextFree(img);

	priv.op   = "Loading";

	img = GP_LoadTmpFile(priv.name, &callback);

	if (img == NULL) {
		fprintf(stderr, "Failed to load temp file %s\n", strerror(errno));
		return 1;
	}

	priv.op   = "Saving";
	priv.name = "out.png";

	printf("\n");

	if (GP_SavePNG(img, "out.png", &callback)) {
		fprintf(stderr, "Failed to save image %s\n", strerror(errno));
		return 1;
	}

	printf("\n");

	return 0;
}
示例#4
0
static int save_load(enum fmt fmt, GP_Size w, GP_Size h)
{
	GP_Context *img, *res;

	img = GP_ContextAlloc(w, h, GP_PIXEL_RGB888);
	
	if (img == NULL) {
		tst_warn("GP_ContextAlloc failed");
		return TST_UNTESTED;
	}

	int ret = save_img(fmt, img, "test");

	if (ret) {
		if (errno == ENOSYS) {
			tst_msg("Save %s: ENOSYS", strfmt(fmt));
			return TST_SKIPPED;
		}
		
		tst_msg("Failed to save %s: %s",
		           strfmt(fmt), strerror(errno));
		return TST_FAILED;
	}

	res = load(fmt, "test");

	if (res == NULL) {
		tst_msg("Failed to load %s: %s",
		           strfmt(fmt), strerror(errno));
		return TST_FAILED;
	}

	GP_ContextFree(img);
	GP_ContextFree(res);

	return TST_SUCCESS;
}
示例#5
0
static int test_load_PNG_check_color(struct check_color_test *test)
{
	GP_Context *img;

	errno = 0;

	img = GP_LoadPNG(test->path, NULL);

	if (img == NULL) {
		switch (errno) {
		case ENOSYS:
			tst_msg("Not Implemented");
			return TST_SKIPPED;
		default:
			tst_msg("Got %s", strerror(errno));
			return TST_FAILED;
		}
	}

	unsigned int x, y, fail = 0;

	for (x = 0; x < img->w; x++) {
		for (y = 0; y < img->w; y++) {
			GP_Pixel p = GP_GetPixel(img, x, y);

			if (p != test->pixel) {
				if (!fail)
					tst_msg("First failed at %u,%u %x %x",
					        x, y, p, test->pixel);
				fail = 1;
			}
		}
	}

	if (!fail)
		tst_msg("Context pixels are correct");

	GP_ContextFree(img);

	if (fail)
		return TST_FAILED;

	return TST_SUCCESS;
}
示例#6
0
文件: GP_Blur.c 项目: m1ch4ls/gfxprim
GP_Context *GP_FilterGaussianBlurExAlloc(const GP_Context *src,
                                         GP_Coord x_src, GP_Coord y_src,
                                         GP_Size w_src, GP_Size h_src,
				         float sigma_x, float sigma_y,
                                         GP_ProgressCallback *callback)
{
	GP_Context *dst = GP_ContextAlloc(w_src, h_src, src->pixel_type);

	if (dst == NULL)
		return NULL;

	if (GP_FilterGaussianBlur_Raw(src, x_src, y_src, w_src, h_src, dst,
	                                0, 0, sigma_x, sigma_y, callback)) {
		GP_ContextFree(dst);
		return NULL;
	}

	return dst;
}
示例#7
0
/*
 * Apply sobel operator.
 */
static int sobel(const GP_Context *src, GP_Context *dx, GP_Context *dy,
                   GP_ProgressCallback *callback)
{
	float dx_kern[] = {
		-1,  0,  1,
		-2,  0,  2,
		-1,  0,  1,
	};

	GP_ConvolutionParams dx_conv = {
		.src = src,
		.x_src = 0,
		.y_src = 0,
		.w_src = src->w,
		.h_src = src->h,
		.dst = dx,
		.x_dst = 0,
		.y_dst = 0,
		.kernel = dx_kern,
		.kw = 3,
		.kh = 3,
		.kern_div = 1,
		.callback = callback,
	};

	if (GP_FilterConvolution_Raw(&dx_conv))
		return 1;

	float dy_kern[] = {
		-1, -2, -1,
		 0,  0,  0,
		 1,  2,  1,
	};

	GP_ConvolutionParams dy_conv = {
		.src = src,
		.x_src = 0,
		.y_src = 0,
		.w_src = src->w,
		.h_src = src->h,
		.dst = dy,
		.x_dst = 0,
		.y_dst = 0,
		.kernel = dy_kern,
		.kw = 3,
		.kh = 3,
		.kern_div = 1,
		.callback = callback,
	};

	if (GP_FilterConvolution_Raw(&dy_conv))
		return 1;

	return 0;
}

static int edge_detect(const GP_Context *src,
                       GP_Context **E, GP_Context **Phi, int type,
		       GP_ProgressCallback *callback)
{
	//TODO
	GP_ASSERT(src->pixel_type == GP_PIXEL_RGB888);

	GP_Context *dx, *dy;

	dx = GP_ContextCopy(src, 0);
	dy = GP_ContextCopy(src, 0);

	if (dx == NULL || dy == NULL)
		goto err0;

	switch (type) {
	case 0:
		if (sobel(src, dx, dy, callback))
			goto err0;
	break;
	case 1:
		if (prewitt(src, dx, dy, callback))
			goto err0;
	break;
	default:
		goto err0;
	}

	uint32_t i, j;

	for (i = 0; i < src->w; i++) {
		for (j = 0; j < src->h; j++) {
			GP_Pixel pix_x = GP_GetPixel_Raw_24BPP(dx, i, j);
			GP_Pixel pix_y = GP_GetPixel_Raw_24BPP(dy, i, j);
			int Rx, Gx, Bx;
			int Ry, Gy, By;
			int RE, GE, BE;
			int RPhi, GPhi, BPhi;

			Rx = GP_Pixel_GET_R_RGB888(pix_x);
			Gx = GP_Pixel_GET_G_RGB888(pix_x);
			Bx = GP_Pixel_GET_B_RGB888(pix_x);

			Ry = GP_Pixel_GET_R_RGB888(pix_y);
			Gy = GP_Pixel_GET_G_RGB888(pix_y);
			By = GP_Pixel_GET_B_RGB888(pix_y);

			RE = sqrt(Rx*Rx + Ry*Ry) + 0.5;
			GE = sqrt(Gx*Gx + Gy*Gy) + 0.5;
			BE = sqrt(Bx*Bx + By*By) + 0.5;

			GP_PutPixel_Raw_24BPP(dx, i, j,
			                      GP_Pixel_CREATE_RGB888(RE, GE, BE));

			if (Rx != 0 && Ry != 0)
				RPhi = ((atan2(Rx, Ry) + M_PI) * 255)/(2*M_PI);
			else
				RPhi = 0;

			if (Gx != 0 && Gy != 0)
				GPhi = ((atan2(Gx, Gy) + M_PI) * 255)/(2*M_PI);
			else
				GPhi = 0;

			if (Bx != 0 && By != 0)
				BPhi = ((atan2(Bx, By) + M_PI) * 255)/(2*M_PI);
			else
				BPhi = 0;

			GP_PutPixel_Raw_24BPP(dy, i, j,
			                      GP_Pixel_CREATE_RGB888(RPhi, GPhi, BPhi));
		}
	}

	if (Phi != NULL)
		*Phi = dy;
	else
		GP_ContextFree(dy);

	if (E != NULL)
		*E = dx;
	else
		GP_ContextFree(dx);

	return 0;
err0:
	GP_ContextFree(dx);
	GP_ContextFree(dy);
	return 1;
}

int GP_FilterEdgeSobel(const GP_Context *src,
                       GP_Context **E, GP_Context **Phi,
                       GP_ProgressCallback *callback)
{
	GP_DEBUG(1, "Sobel edge detection image %ux%u", src->w, src->h);

	return edge_detect(src, E, Phi, 0, callback);
}
示例#8
0
int GP_ReadJPGEx(GP_IO *io, GP_Context **img,
		 GP_DataStorage *storage, GP_ProgressCallback *callback)
{
	struct jpeg_decompress_struct cinfo;
	struct my_source_mgr src;
	struct my_jpg_err my_err;
	GP_Context *ret = NULL;
	uint8_t buf[1024];
	int err;

	cinfo.err = jpeg_std_error(&my_err.error_mgr);
	my_err.error_mgr.error_exit = my_error_exit;

	if (setjmp(my_err.setjmp_buf)) {
		err = EIO;
		goto err2;
	}

	jpeg_create_decompress(&cinfo);
	init_source_mgr(&src, io, buf, sizeof(buf));
	cinfo.src = (void*)&src;

	if (storage)
		save_jpg_markers(&cinfo);

	jpeg_read_header(&cinfo, TRUE);

	GP_DEBUG(1, "Have %s JPEG size %ux%u %i channels",
	            get_colorspace(cinfo.jpeg_color_space),
	            cinfo.image_width, cinfo.image_height,
		    cinfo.num_components);

	//TODO: Propagate failure?
	if (storage)
		read_jpg_metadata(&cinfo, storage);

	if (!img)
		goto exit;

	GP_Pixel pixel_type;

	switch (cinfo.out_color_space) {
	case JCS_GRAYSCALE:
		pixel_type = GP_PIXEL_G8;
	break;
	case JCS_RGB:
		pixel_type = GP_PIXEL_BGR888;
	break;
	case JCS_CMYK:
		pixel_type = GP_PIXEL_CMYK8888;
	break;
	default:
		pixel_type = GP_PIXEL_UNKNOWN;
	}

	if (pixel_type == GP_PIXEL_UNKNOWN) {
		GP_DEBUG(1, "Can't handle %s JPEG output format",
		            get_colorspace(cinfo.out_color_space));
		err = ENOSYS;
		goto err1;
	}

	ret = GP_ContextAlloc(cinfo.image_width, cinfo.image_height,
	                      pixel_type);

	if (ret == NULL) {
		GP_DEBUG(1, "Malloc failed :(");
		err = ENOMEM;
		goto err1;
	}

	jpeg_start_decompress(&cinfo);

	switch (pixel_type) {
	case GP_PIXEL_BGR888:
	case GP_PIXEL_G8:
		err = load(&cinfo, ret, callback);
	break;
	case GP_PIXEL_CMYK8888:
		err = load_cmyk(&cinfo, ret, callback);
	break;
	default:
		err = EINVAL;
	}

	if (err)
		goto err2;

	jpeg_finish_decompress(&cinfo);
exit:
	jpeg_destroy_decompress(&cinfo);

	GP_ProgressCallbackDone(callback);

	if (img)
		*img = ret;

	return 0;
err2:
	GP_ContextFree(ret);
err1:
	jpeg_destroy_decompress(&cinfo);
	errno = err;
	return 1;
}
示例#9
0
int GP_ReadGIFEx(GP_IO *io, GP_Context **img,
                 GP_DataStorage *storage, GP_ProgressCallback *callback)
{
	GifFileType *gf;
	GifRecordType rec_type;
	GP_Context *res = NULL;
	GP_Pixel bg;
	int32_t x, y;
	int err;

	errno = 0;
#if defined(GIFLIB_MAJOR) && GIFLIB_MAJOR >= 5
	gf = DGifOpen(io, gif_input_func, NULL);
#else
	gf = DGifOpen(io, gif_input_func);
#endif

	if (gf == NULL) {
		/*
		 * The giflib uses open() so when we got a failure and errno
		 * is set => open() has failed.
		 *
		 * When errno is not set the file content was not valid so we
		 * set errno to EIO.
		 */
		if (errno == 0)
			errno = EIO;

		return 1;
	}

	GP_DEBUG(1, "Have GIF image %ix%i, %i colors, %i bpp",
	         gf->SWidth, gf->SHeight, gf->SColorResolution,
		 gf->SColorMap ? gf->SColorMap->BitsPerPixel : -1);

	do {
		if (DGifGetRecordType(gf, &rec_type) != GIF_OK) {
			//TODO: error handling
			GP_DEBUG(1, "DGifGetRecordType() error %s (%i)",
			         gif_err_name(gif_err(gf)), gif_err(gf));
			err = EIO;
			goto err1;
		}

		GP_DEBUG(2, "Have GIF record type %s",
		         rec_type_name(rec_type));

		switch (rec_type) {
		case EXTENSION_RECORD_TYPE:
			if ((err = read_extensions(gf)))
				goto err1;
			continue;
		case IMAGE_DESC_RECORD_TYPE:
		break;
		default:
			continue;
		}

		if (DGifGetImageDesc(gf) != GIF_OK) {
			//TODO: error handling
			GP_DEBUG(1, "DGifGetImageDesc() error %s (%i)",
			         gif_err_name(gif_err(gf)), gif_err(gf)); 
			err = EIO;
			goto err1;
		}

		if (storage)
			fill_metadata(gf, storage);

		GP_DEBUG(1, "Have GIF Image left-top %ix%i, width-height %ix%i,"
		         " interlace %i, bpp %i", gf->Image.Left, gf->Image.Top,
			 gf->Image.Width, gf->Image.Height, gf->Image.Interlace,
			 gf->Image.ColorMap ? gf->Image.ColorMap->BitsPerPixel : -1);

		if (!img)
			break;

		res = GP_ContextAlloc(gf->SWidth, gf->SHeight, GP_PIXEL_RGB888);

		if (res == NULL) {
			err = ENOMEM;
			goto err1;
		}

		/* If background color is defined, use it */
		if (get_bg_color(gf, &bg)) {
			GP_DEBUG(1, "Filling bg color %x", bg);
			GP_Fill(res, bg);
		}

		/* Now finally read gif image data */
		for (y = gf->Image.Top; y < gf->Image.Height; y++) {
			uint8_t line[gf->Image.Width];

			DGifGetLine(gf, line, gf->Image.Width);

			unsigned int real_y = y;

			if (gf->Image.Interlace == 64) {
				real_y = interlace_real_y(gf, y);
				GP_DEBUG(3, "Interlace y -> real_y %u %u", y, real_y);
			}

			//TODO: just now we have only 8BPP
			for (x = 0; x < gf->Image.Width; x++)
				GP_PutPixel_Raw_24BPP(res, x + gf->Image.Left, real_y, get_color(gf, line[x]));

			if (GP_ProgressCallbackReport(callback, y - gf->Image.Top,
			                              gf->Image.Height,
						      gf->Image.Width)) {
				GP_DEBUG(1, "Operation aborted");
				err = ECANCELED;
				goto err2;
			}
		}

		//TODO: now we exit after reading first image
		break;

	} while (rec_type != TERMINATE_RECORD_TYPE);

	DGifCloseFile(gf);

	/* No Image record found :( */
	if (img && !res) {
		errno = EINVAL;
		return 1;
	}

	if (img)
		*img = res;

	return 0;
err2:
	GP_ContextFree(res);
err1:
	DGifCloseFile(gf);
	errno = err;
	return 1;
}