mirror of
https://projects.vdr-developer.org/git/vdr-plugin-scraper2vdr.git
synced 2023-10-19 17:58:31 +02:00
191 lines
4.8 KiB
C
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;
|
||
|
}
|