Пример #1
0
static int save_convert(struct jpeg_compress_struct *cinfo,
                        const GP_Context *src,
                        GP_PixelType out_pix,
                        GP_ProgressCallback *callback)
{
	uint8_t tmp[(src->w * GP_PixelSize(out_pix)) / 8 + 1];
	GP_LineConvert Convert;

	Convert = GP_LineConvertGet(src->pixel_type, out_pix);

	while (cinfo->next_scanline < cinfo->image_height) {
		uint32_t y = cinfo->next_scanline;
		void *in = GP_PIXEL_ADDR(src, 0, y);

		Convert(in, tmp, src->w);

		JSAMPROW row = (void*)tmp;
		jpeg_write_scanlines(cinfo, &row, 1);

		if (GP_ProgressCallbackReport(callback, y, src->h, src->w)) {
			GP_DEBUG(1, "Operation aborted");
			return ECANCELED;
		}
	}

	return 0;
}
Пример #2
0
static int load_cmyk(struct jpeg_decompress_struct *cinfo, GP_Context *ret,
                       GP_ProgressCallback *callback)
{
	while (cinfo->output_scanline < cinfo->output_height) {
		uint32_t y = cinfo->output_scanline;

		JSAMPROW addr = (void*)GP_PIXEL_ADDR(ret, 0, y);
		jpeg_read_scanlines(cinfo, &addr, 1);

		unsigned int i;
		uint8_t *buf = GP_PIXEL_ADDR(ret, 0, y);

		for (i = 0; i < ret->w; i++) {
			unsigned int j = 4 * i;

			buf[j]   = 0xff - buf[j];
			buf[j+1] = 0xff - buf[j+1];
			buf[j+2] = 0xff - buf[j+2];
			buf[j+3] = 0xff - buf[j+3];
		}

		if (GP_ProgressCallbackReport(callback, y, ret->h, ret->w)) {
			GP_DEBUG(1, "Operation aborted");
			return ECANCELED;
		}
	}

	return 0;
}
Пример #3
0
static int load(struct jpeg_decompress_struct *cinfo, GP_Context *ret,
                GP_ProgressCallback *callback)
{
	while (cinfo->output_scanline < cinfo->output_height) {
		uint32_t y = cinfo->output_scanline;
                JSAMPROW addr = (void*)GP_PIXEL_ADDR(ret, 0, y);

		jpeg_read_scanlines(cinfo, &addr, 1);

		if (GP_ProgressCallbackReport(callback, y, ret->h, ret->w)) {
			GP_DEBUG(1, "Operation aborted");
			return ECANCELED;
		}
	}

	return 0;
}
Пример #4
0
static int save(struct jpeg_compress_struct *cinfo,
                const GP_Context *src,
                GP_ProgressCallback *callback)
{
	while (cinfo->next_scanline < cinfo->image_height) {
		uint32_t y = cinfo->next_scanline;

		JSAMPROW row = (void*)GP_PIXEL_ADDR(src, 0, y);
		jpeg_write_scanlines(cinfo, &row, 1);

		if (GP_ProgressCallbackReport(callback, y, src->h, src->w)) {
			GP_DEBUG(1, "Operation aborted");
			return ECANCELED;
		}
	}

	return 0;
}
Пример #5
0
int GP_ReadJP2Ex(GP_IO *io, GP_Context **rimg, GP_DataStorage *storage,
                 GP_ProgressCallback *callback)
{
	opj_dparameters_t params;
	opj_codec_t *codec;
	opj_stream_t *stream;
	opj_image_t *img;

	GP_PixelType pixel_type;
	GP_Context *res = NULL;
	unsigned int i, x, y;
	int err = 0, ret = 1;

	opj_set_default_decoder_parameters(&params);

	codec = opj_create_decompress(OPJ_CODEC_JP2);

	if (!codec) {
		GP_DEBUG(1, "opj_create_decompress failed");
		err = ENOMEM;
		goto err0;
	}

	opj_set_error_handler(codec, jp2_err_callback, NULL);
	opj_set_warning_handler(codec, jp2_warn_callback, NULL);
	opj_set_info_handler(codec, jp2_info_callback, callback);

	if (!opj_setup_decoder(codec, &params)) {
		GP_DEBUG(1, "opj_setup_decoder failed");
		err = ENOMEM;
		goto err1;
	}

	stream = opj_stream_default_create(OPJ_TRUE);

	if (!stream) {
		GP_DEBUG(1, "opj_stream_create_default_file_stream faled");
		err = ENOMEM;
		goto err1;
	}

	//TODO: Do we need seek and skip?
	opj_stream_set_read_function(stream, jp2_io_read);
	opj_stream_set_user_data(stream, io);

	if (!opj_read_header(stream, codec, &img)) {
		GP_DEBUG(1, "opj_read_header failed");
		err = EINVAL;
		goto err2;
	}

	if (storage)
		fill_metadata(img, storage);

	GP_DEBUG(1, "Have image %ux%u-%ux%u colorspace=%s numcomps=%u",
	         img->x0, img->y0, img->x1, img->y1,
	         color_space_name(img->color_space), img->numcomps);

	if (!rimg)
		return 0;

	/*
	 * Try to match the image information into pixel type.
	 *
	 * Unfortunately the images I had have color_space set
	 * to unspecified yet they were RGB888.
	 */
	for (i = 0; i < img->numcomps; i++) {
		opj_image_comp_t *comp = &img->comps[i];

		GP_DEBUG(2, "Component %u %ux%u bpp=%u",
		         i, comp->w, comp->h, comp->prec);

		if (comp->w != img->comps[0].w ||
		    comp->h != img->comps[0].h) {
			GP_DEBUG(1, "Component %u has different size", 1);
			err = ENOSYS;
			goto err3;
		}

		if (comp->prec != 8) {
			GP_DEBUG(1, "Component %u has different bpp", 1);
			err = ENOSYS;
			goto err3;
		}
	}

	switch (img->color_space) {
	case OPJ_CLRSPC_UNSPECIFIED:
		if (img->numcomps != 3) {
			GP_DEBUG(1, "Unexpected number of components");
			err = ENOSYS;
			goto err3;
		}
		pixel_type = GP_PIXEL_RGB888;
	break;
	default:
		GP_DEBUG(1, "Unsupported colorspace");
		err = ENOSYS;
		goto err3;
	}

	GP_ProgressCallbackReport(callback, 0, 100, 100);

	if (!opj_decode(codec, stream, img)) {
		GP_DEBUG(1, "opj_decode failed");
		err = EINVAL;
		goto err3;
	}

	res = GP_ContextAlloc(img->comps[0].w, img->comps[0].h, pixel_type);

	if (!res) {
		GP_DEBUG(1, "Malloc failed :(");
		err = ENOMEM;
		goto err3;
	}

	for (y = 0; y < res->h; y++) {
		for (x = 0; x < res->w; x++) {
			i = y * res->w + x;

			GP_Pixel p = img->comps[0].data[i] << 16|
			             img->comps[1].data[i] << 8 |
			             img->comps[2].data[i];

			GP_PutPixel_Raw_24BPP(res, x, y, p);
		}
	}

	GP_ProgressCallbackDone(callback);
	*rimg = res;
	ret = 0;
err3:
	opj_image_destroy(img);
err2:
	opj_stream_destroy(stream);
err1:
	opj_destroy_codec(codec);
err0:
	if (err)
		errno = err;
	return ret;
}
Пример #6
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;
}