vdr-plugin-scraper2vdr/lib/imgtools.c
2014-05-09 16:20:06 +02:00

191 lines
4.8 KiB
C

/*
* imgtools.c
*
* See the README file for copyright information and how to reach the author.
*
*/
#include "imgtools.h"
//***************************************************************************
// Image converting stuff
//***************************************************************************
int fromJpeg(Imlib_Image& image, unsigned char* buffer, int size)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
int w, h;
DATA8 *ptr, *line[16], *data;
DATA32 *ptr2, *dest;
int x, y;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_mem_src(&cinfo, buffer, size);
jpeg_read_header(&cinfo, TRUE);
cinfo.do_fancy_upsampling = FALSE;
cinfo.do_block_smoothing = FALSE;
jpeg_start_decompress(&cinfo);
w = cinfo.output_width;
h = cinfo.output_height;
image = imlib_create_image(w, h);
imlib_context_set_image(image);
dest = ptr2 = imlib_image_get_data();
data = (DATA8*)malloc(w * 16 * cinfo.output_components);
for (int i = 0; i < cinfo.rec_outbuf_height; i++)
line[i] = data + (i * w * cinfo.output_components);
for (int l = 0; l < h; l += cinfo.rec_outbuf_height)
{
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
int scans = cinfo.rec_outbuf_height;
if (h - l < scans)
scans = h - l;
ptr = data;
for (y = 0; y < scans; y++)
{
for (x = 0; x < w; x++)
{
*ptr2 = (0xff000000) | ((ptr[0]) << 16) | ((ptr[1]) << 8) | (ptr[2]);
ptr += cinfo.output_components;
ptr2++;
}
}
}
free(data);
imlib_image_put_back_data(dest);
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
return success;
}
long toJpeg(Imlib_Image image, MemoryStruct* data, int quality)
{
struct jpeg_compress_struct cinfo = { 0 };
struct jpeg_error_mgr jerr;
DATA32* ptr;
DATA8* buf;
long unsigned int size = data->size;
imlib_context_set_image(image);
data->clear();
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_mem_dest(&cinfo, (unsigned char**)(&data->memory), &size);
cinfo.image_width = imlib_image_get_width();
cinfo.image_height = imlib_image_get_height();
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE);
jpeg_start_compress(&cinfo, TRUE);
// get data pointer
if (!(ptr = imlib_image_get_data_for_reading_only()))
return 0;
// allocate a small buffer to convert image data */
buf = (DATA8*)malloc(imlib_image_get_width() * 3 * sizeof(DATA8));
while (cinfo.next_scanline < cinfo.image_height)
{
// convert scanline from ARGB to RGB packed
for (int j = 0, i = 0; i < imlib_image_get_width(); i++)
{
buf[j++] = ((*ptr) >> 16) & 0xff;
buf[j++] = ((*ptr) >> 8) & 0xff;
buf[j++] = ((*ptr)) & 0xff;
ptr++;
}
// write scanline
jpeg_write_scanlines(&cinfo, (JSAMPROW*)(&buf), 1);
}
free(buf);
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
return data->size;
}
int scaleImageToJpegBuffer(Imlib_Image image, MemoryStruct* data, int width, int height)
{
if (width && height)
{
Imlib_Image scaledImage;
imlib_context_set_image(image);
int imgWidth = imlib_image_get_width();
int imgHeight = imlib_image_get_height();
double ratio = (double)imgWidth / (double)imgHeight;
if ((double)width/(double)imgWidth < (double)height/(double)imgHeight)
height = (int)((double)width / ratio);
else
width = (int)((double)height * ratio);
scaledImage = imlib_create_image(width, height);
imlib_context_set_image(scaledImage);
imlib_context_set_color(240, 240, 240, 255);
imlib_image_fill_rectangle(0, 0, width, height);
imlib_blend_image_onto_image(image, 0, 0, 0,
imgWidth, imgHeight, 0, 0,
width, height);
toJpeg(scaledImage, data, 70);
imlib_context_set_image(scaledImage);
imlib_free_image();
tell(1, "Scaled image to %d/%d, now %d bytes", width, height, (int)data->size);
}
else
{
toJpeg(image, data, 70);
}
return success;
}
int scaleJpegBuffer(MemoryStruct* data, int width, int height)
{
Imlib_Image image;
fromJpeg(image, (unsigned char*)data->memory, data->size);
scaleImageToJpegBuffer(image, data, width, height);
imlib_context_set_image(image);
imlib_free_image();
return success;
}