mirror of
https://projects.vdr-developer.org/git/vdr-plugin-skindesigner.git
synced 2023-10-19 17:58:31 +02:00
Added JPEG support
This commit is contained in:
parent
052bc50408
commit
e07e56a3fa
4
Makefile
4
Makefile
@ -44,8 +44,8 @@ DEFINES += $(shell xml2-config --cflags)
|
||||
|
||||
INCLUDES += $(shell pkg-config --cflags freetype2 fontconfig)
|
||||
|
||||
INCLUDES += $(shell pkg-config --cflags librsvg-2.0 cairo-png)
|
||||
LIBS += $(shell pkg-config --libs librsvg-2.0 cairo-png)
|
||||
INCLUDES += $(shell pkg-config --cflags librsvg-2.0 cairo-png) -ljpeg
|
||||
LIBS += $(shell pkg-config --libs librsvg-2.0 cairo-png) -ljpeg
|
||||
|
||||
LIBS += $(shell xml2-config --libs)
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "../config.h"
|
||||
#include "helpers.h"
|
||||
#include "imageloader.h"
|
||||
//#include <math.h>
|
||||
#include <string>
|
||||
#include <dirent.h>
|
||||
#include <iostream>
|
||||
@ -69,6 +68,8 @@ bool cImageLoader::LoadImage(const char *fullpath) {
|
||||
importer = new cImageImporterPNG;
|
||||
else if (endswith(fullpath, ".svg"))
|
||||
importer = new cImageImporterSVG;
|
||||
else if (endswith(fullpath, ".jpg"))
|
||||
importer = new cImageImporterJPG;
|
||||
else
|
||||
return false;
|
||||
|
||||
@ -209,3 +210,137 @@ void cImageImporterSVG::GetImageSize(int &width, int &height) {
|
||||
height = dim.height;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Image importer for JPG
|
||||
//
|
||||
|
||||
cImageImporterJPG::cImageImporterJPG() {
|
||||
cinfo = NULL;
|
||||
}
|
||||
|
||||
cImageImporterJPG::~cImageImporterJPG() {
|
||||
if (cinfo) {
|
||||
jpeg_destroy_decompress(cinfo);
|
||||
free(cinfo);
|
||||
fclose(infile);
|
||||
}
|
||||
}
|
||||
|
||||
bool cImageImporterJPG::LoadImage(const char *path) {
|
||||
if (cinfo) {
|
||||
jpeg_destroy_decompress(cinfo);
|
||||
free(cinfo);
|
||||
fclose(infile);
|
||||
cinfo = NULL;
|
||||
}
|
||||
|
||||
// Open input file
|
||||
if ((infile = fopen(path, "rb")) == NULL) {
|
||||
if (config.debugImageLoading)
|
||||
dsyslog("skindesigner: Can't open %s", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
// We set up the normal JPEG error routines, then override error_exit.
|
||||
struct my_error_mgr jerr;
|
||||
cinfo = (j_decompress_ptr)malloc(sizeof(struct jpeg_decompress_struct));
|
||||
cinfo->err = jpeg_std_error(&jerr.pub);
|
||||
jerr.pub.error_exit = my_error_exit;
|
||||
jerr.pub.output_message = my_output_message;
|
||||
// Establish the setjmp return context for my_error_exit to use.
|
||||
if (setjmp(jerr.setjmp_buffer)) {
|
||||
// If we get here, the JPEG code has signaled an error.
|
||||
jpeg_destroy_decompress(cinfo);
|
||||
free(cinfo);
|
||||
fclose(infile);
|
||||
cinfo = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now we can initialize the JPEG decompression object.
|
||||
jpeg_create_decompress(cinfo);
|
||||
|
||||
// Step 2: specify data source (eg, a file)
|
||||
jpeg_stdio_src(cinfo, infile);
|
||||
|
||||
// Step 3: read file parameters with jpeg_read_header()
|
||||
(void) jpeg_read_header(cinfo, TRUE);
|
||||
return true;
|
||||
}
|
||||
|
||||
void cImageImporterJPG::DrawToCairo(cairo_t *cr) {
|
||||
if (!cinfo)
|
||||
return;
|
||||
|
||||
unsigned char *bmp_buffer = NULL;
|
||||
|
||||
// Re-establish error handling
|
||||
struct my_error_mgr jerr;
|
||||
cinfo->err = jpeg_std_error(&jerr.pub);
|
||||
jerr.pub.error_exit = my_error_exit;
|
||||
jerr.pub.output_message = my_output_message;
|
||||
if (setjmp(jerr.setjmp_buffer)) {
|
||||
jpeg_destroy_decompress(cinfo);
|
||||
free(cinfo);
|
||||
fclose(infile);
|
||||
free(bmp_buffer);
|
||||
cinfo = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 4: set parameters for decompression
|
||||
cinfo->out_color_space = JCS_EXT_ARGB;
|
||||
|
||||
// Step 5: Start decompressor
|
||||
(void) jpeg_start_decompress(cinfo);
|
||||
|
||||
// Bytes per row in output buffer
|
||||
int row_stride = cinfo->output_width * cinfo->output_components;
|
||||
|
||||
// Allocate buffer
|
||||
unsigned long bmp_size = row_stride * cinfo->output_height;
|
||||
bmp_buffer = (unsigned char*)malloc(bmp_size);
|
||||
|
||||
// Step 6: while (scan lines remain to be read)
|
||||
while (cinfo->output_scanline < cinfo->output_height) {
|
||||
unsigned char *buffer_array[1];
|
||||
buffer_array[0] = bmp_buffer + (cinfo->output_scanline) * row_stride;
|
||||
jpeg_read_scanlines(cinfo, buffer_array, 1);
|
||||
}
|
||||
|
||||
// Step 7: Finish decompression
|
||||
(void)jpeg_finish_decompress(cinfo);
|
||||
fclose(infile);
|
||||
|
||||
// --> At this point we have raw RGB data in bmp_buffer
|
||||
|
||||
// Create new Cairo surface from our raw image data
|
||||
cairo_surface_t *surface;
|
||||
surface = cairo_image_surface_create_for_data(bmp_buffer,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
cinfo->output_width,
|
||||
cinfo->output_height,
|
||||
row_stride);
|
||||
|
||||
// Draw surface to Cairo
|
||||
if (surface) {
|
||||
cairo_set_source_surface(cr, surface, 0, 0);
|
||||
cairo_paint(cr);
|
||||
cairo_surface_destroy(surface);
|
||||
}
|
||||
|
||||
// Cleanup. In this "ImageImporter" we clean up everything in "DrawToCairo"
|
||||
// as I'm not really sure whether we are able to draw a second time.
|
||||
free(bmp_buffer);
|
||||
jpeg_destroy_decompress(cinfo);
|
||||
free(cinfo);
|
||||
cinfo = NULL;
|
||||
}
|
||||
|
||||
void cImageImporterJPG::GetImageSize(int &width, int &height) {
|
||||
if (cinfo) {
|
||||
width = cinfo->image_width;
|
||||
height = cinfo->image_height;
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
#ifndef __NOPACITY_IMAGELOADER_H
|
||||
#define __NOPACITY_IMAGELOADER_H
|
||||
|
||||
#define X_DISPLAY_MISSING
|
||||
|
||||
#include <cairo.h>
|
||||
#include <librsvg/rsvg.h>
|
||||
#include <jpeglib.h>
|
||||
#include <setjmp.h>
|
||||
#include <vdr/osd.h>
|
||||
#include <vdr/tools.h>
|
||||
|
||||
@ -44,6 +44,53 @@ private:
|
||||
RsvgHandle *handle;
|
||||
};
|
||||
|
||||
// Image importer for JPG
|
||||
|
||||
#if BITS_IN_JSAMPLE != 8
|
||||
#error libjpeg-turbo has to be compiled with 8-bit samples!
|
||||
#endif
|
||||
#ifndef JCS_EXTENSIONS
|
||||
#error libjpeg-turbo with JCS_EXTENSIONS required!
|
||||
#endif
|
||||
|
||||
struct my_error_mgr {
|
||||
struct jpeg_error_mgr pub; // "public" fields
|
||||
jmp_buf setjmp_buffer; // for return to caller
|
||||
};
|
||||
|
||||
METHODDEF(void)
|
||||
my_error_exit(j_common_ptr cinfo) {
|
||||
// cinfo->err really points to a my_error_mgr struct, so coerce pointer
|
||||
my_error_mgr *myerr = (my_error_mgr*) cinfo->err;
|
||||
|
||||
// Always display the message.
|
||||
// We could postpone this until after returning, if we chose.
|
||||
(*cinfo->err->output_message) (cinfo);
|
||||
|
||||
// Return control to the setjmp point
|
||||
longjmp(myerr->setjmp_buffer, 1);
|
||||
}
|
||||
|
||||
METHODDEF(void)
|
||||
my_output_message(j_common_ptr cinfo) {
|
||||
char buf[JMSG_LENGTH_MAX];
|
||||
cinfo->err->format_message(cinfo, buf);
|
||||
dsyslog("skindesigner: libjpeg error: %s", buf);
|
||||
}
|
||||
|
||||
class cImageImporterJPG : public cImageImporter {
|
||||
public:
|
||||
cImageImporterJPG();
|
||||
~cImageImporterJPG();
|
||||
bool LoadImage(const char *path);
|
||||
void DrawToCairo(cairo_t *cr);
|
||||
void GetImageSize(int &width, int &height);
|
||||
private:
|
||||
j_decompress_ptr cinfo;
|
||||
FILE *infile;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class cImageLoader {
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user