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 freetype2 fontconfig)
|
||||||
|
|
||||||
INCLUDES += $(shell pkg-config --cflags 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)
|
LIBS += $(shell pkg-config --libs librsvg-2.0 cairo-png) -ljpeg
|
||||||
|
|
||||||
LIBS += $(shell xml2-config --libs)
|
LIBS += $(shell xml2-config --libs)
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "imageloader.h"
|
#include "imageloader.h"
|
||||||
//#include <math.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -69,6 +68,8 @@ bool cImageLoader::LoadImage(const char *fullpath) {
|
|||||||
importer = new cImageImporterPNG;
|
importer = new cImageImporterPNG;
|
||||||
else if (endswith(fullpath, ".svg"))
|
else if (endswith(fullpath, ".svg"))
|
||||||
importer = new cImageImporterSVG;
|
importer = new cImageImporterSVG;
|
||||||
|
else if (endswith(fullpath, ".jpg"))
|
||||||
|
importer = new cImageImporterJPG;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -209,3 +210,137 @@ void cImageImporterSVG::GetImageSize(int &width, int &height) {
|
|||||||
height = dim.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
|
#ifndef __NOPACITY_IMAGELOADER_H
|
||||||
#define __NOPACITY_IMAGELOADER_H
|
#define __NOPACITY_IMAGELOADER_H
|
||||||
|
|
||||||
#define X_DISPLAY_MISSING
|
|
||||||
|
|
||||||
#include <cairo.h>
|
#include <cairo.h>
|
||||||
#include <librsvg/rsvg.h>
|
#include <librsvg/rsvg.h>
|
||||||
|
#include <jpeglib.h>
|
||||||
|
#include <setjmp.h>
|
||||||
#include <vdr/osd.h>
|
#include <vdr/osd.h>
|
||||||
#include <vdr/tools.h>
|
#include <vdr/tools.h>
|
||||||
|
|
||||||
@ -44,6 +44,53 @@ private:
|
|||||||
RsvgHandle *handle;
|
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 {
|
class cImageLoader {
|
||||||
private:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user