mirror of
https://github.com/netsurf-browser/netsurf
synced 2025-01-11 21:39:56 +03:00
[project @ 2004-03-23 22:17:08 by bursa]
Remove usage of OS JPEG module; convert all JPEGs to 32bpp and plot with Tinct; speed improvements and cleanup. svn path=/import/netsurf/; revision=656
This commit is contained in:
parent
667bb92e9d
commit
31e521a02e
483
riscos/jpeg.c
483
riscos/jpeg.c
@ -2,357 +2,244 @@
|
|||||||
* This file is part of NetSurf, http://netsurf.sourceforge.net/
|
* This file is part of NetSurf, http://netsurf.sourceforge.net/
|
||||||
* Licensed under the GNU General Public License,
|
* Licensed under the GNU General Public License,
|
||||||
* http://www.opensource.org/licenses/gpl-license
|
* http://www.opensource.org/licenses/gpl-license
|
||||||
* Copyright 2003 James Bursa <bursa@users.sourceforge.net>
|
* Copyright 2004 James Bursa <bursa@users.sourceforge.net>
|
||||||
* Copyright 2004 John M Bell <jmb202@ecs.soton.ac.uk>
|
* Copyright 2004 John M Bell <jmb202@ecs.soton.ac.uk>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/** \file
|
||||||
|
* Content for image/jpeg (implementation).
|
||||||
|
*
|
||||||
|
* This implementation uses the IJG JPEG library.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
#include <swis.h>
|
||||||
|
#define JPEG_INTERNAL_OPTIONS
|
||||||
#include "libjpeg/jpeglib.h"
|
#include "libjpeg/jpeglib.h"
|
||||||
#include "oslib/colourtrans.h"
|
#include "oslib/colourtrans.h"
|
||||||
#include "oslib/jpeg.h"
|
|
||||||
#include "oslib/osbyte.h"
|
|
||||||
#include "oslib/osfile.h"
|
|
||||||
#include "oslib/osspriteop.h"
|
#include "oslib/osspriteop.h"
|
||||||
#include "netsurf/utils/config.h"
|
#include "netsurf/utils/config.h"
|
||||||
#include "netsurf/content/content.h"
|
#include "netsurf/content/content.h"
|
||||||
#include "netsurf/desktop/gui.h"
|
#include "netsurf/desktop/gui.h"
|
||||||
#include "netsurf/riscos/jpeg.h"
|
#include "netsurf/riscos/jpeg.h"
|
||||||
|
#include "netsurf/riscos/options.h"
|
||||||
|
#include "netsurf/riscos/tinct.h"
|
||||||
#include "netsurf/utils/log.h"
|
#include "netsurf/utils/log.h"
|
||||||
#include "netsurf/utils/messages.h"
|
#include "netsurf/utils/messages.h"
|
||||||
#include "netsurf/utils/utils.h"
|
#include "netsurf/utils/utils.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* screen mode image result
|
|
||||||
* 8bpp or less 8, 16 or 24bpp dither to 8bpp
|
|
||||||
* 16 or 24bpp 8, 16 or 24bpp 24bpp sprite
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef WITH_JPEG
|
/* We require a the library to be configured with these options to save
|
||||||
/**
|
* copying data during decoding. */
|
||||||
* Input source initalisation routine
|
#if RGB_RED != 0 || RGB_GREEN != 1 || RGB_BLUE != 2 || RGB_PIXELSIZE != 4
|
||||||
* Does nothing.
|
#error JPEG library incorrectly configured.
|
||||||
*/
|
#endif
|
||||||
static void init_source(j_decompress_ptr cinfo) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Routine to fill the input buffer.
|
|
||||||
* Filling buffer is not possible => return false.
|
|
||||||
*/
|
|
||||||
static boolean fill_input_buffer(j_decompress_ptr cinfo) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) {
|
|
||||||
if ((int)num_bytes > (int)cinfo->src->bytes_in_buffer) {
|
|
||||||
cinfo->src->next_input_byte = NULL;
|
|
||||||
cinfo->src->bytes_in_buffer = 0;
|
|
||||||
} else {
|
|
||||||
cinfo->src->next_input_byte += (int) num_bytes;
|
|
||||||
cinfo->src->bytes_in_buffer -= (int) num_bytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Input source termination routine
|
|
||||||
* Does nothing
|
|
||||||
*/
|
|
||||||
static void term_source(j_decompress_ptr cinfo) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Input source manager.
|
|
||||||
* Sets up jpeglib appropriately
|
|
||||||
*/
|
|
||||||
static void jpeg_memory_src(j_decompress_ptr cinfo, char *ptr, unsigned long length) {
|
|
||||||
|
|
||||||
struct jpeg_source_mgr *src;
|
|
||||||
src = cinfo->src = (struct jpeg_source_mgr *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo,
|
|
||||||
JPOOL_IMAGE,
|
|
||||||
sizeof(*src));
|
|
||||||
src->init_source = init_source;
|
|
||||||
src->fill_input_buffer = fill_input_buffer;
|
|
||||||
src->skip_input_data = skip_input_data;
|
|
||||||
src->resync_to_restart = jpeg_resync_to_restart;
|
|
||||||
src->term_source = term_source;
|
|
||||||
src->next_input_byte = ptr;
|
|
||||||
src->bytes_in_buffer = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Error handling stuff.
|
|
||||||
This prevents jpeglib calling exit() on a fatal error */
|
|
||||||
struct nsjpeg_error_mgr {
|
struct nsjpeg_error_mgr {
|
||||||
struct jpeg_error_mgr pub;
|
struct jpeg_error_mgr pub;
|
||||||
jmp_buf setjmp_buffer;
|
jmp_buf setjmp_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct nsjpeg_error_mgr * nsjpeg_err_ptr;
|
|
||||||
|
|
||||||
METHODDEF (void) nsjpeg_error_exit (j_common_ptr cinfo) {
|
static void nsjpeg_error_exit(j_common_ptr cinfo);
|
||||||
|
static void nsjpeg_init_source(j_decompress_ptr cinfo);
|
||||||
|
static boolean nsjpeg_fill_input_buffer(j_decompress_ptr cinfo);
|
||||||
|
static void nsjpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes);
|
||||||
|
static void nsjpeg_term_source(j_decompress_ptr cinfo);
|
||||||
|
|
||||||
nsjpeg_err_ptr myerr = (nsjpeg_err_ptr)cinfo->err;
|
|
||||||
|
|
||||||
(*cinfo->err->output_message) (cinfo);
|
|
||||||
|
|
||||||
longjmp(myerr->setjmp_buffer, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** maps colours to 256 mode colour numbers */
|
|
||||||
static os_colour_number colour_table[4096];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialises the jpeg loader.
|
* Create a CONTENT_JPEG.
|
||||||
* Currently creates the 8bpp lookup table
|
|
||||||
*/
|
*/
|
||||||
void nsjpeg_init(void) {
|
|
||||||
|
|
||||||
unsigned int red, green, blue;
|
|
||||||
/* generate colour lookup table for reducing to 8bpp */
|
|
||||||
for (red = 0; red != 0x10; red++)
|
|
||||||
for (green = 0; green != 0x10; green++)
|
|
||||||
for (blue = 0; blue != 0x10; blue++)
|
|
||||||
colour_table[red << 8 | green << 4 | blue] =
|
|
||||||
colourtrans_return_colour_number_for_mode(
|
|
||||||
blue << 28 | blue << 24 |
|
|
||||||
green << 20 | green << 16 |
|
|
||||||
red << 12 | red << 8,
|
|
||||||
(os_mode)21, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsjpeg_create(struct content *c, const char *params[])
|
void nsjpeg_create(struct content *c, const char *params[])
|
||||||
{
|
{
|
||||||
c->data.jpeg.sprite_area = 0;
|
c->data.jpeg.sprite_area = 0;
|
||||||
c->data.jpeg.use_module = true; /* assume the OS can cope */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int nsjpeg_convert(struct content *c, unsigned int width, unsigned int height)
|
/**
|
||||||
|
* Convert a CONTENT_JPEG for display.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int nsjpeg_convert(struct content *c, unsigned int w, unsigned int h)
|
||||||
{
|
{
|
||||||
struct jpeg_decompress_struct cinfo;
|
struct jpeg_decompress_struct cinfo;
|
||||||
struct nsjpeg_error_mgr jerr;
|
struct nsjpeg_error_mgr jerr;
|
||||||
unsigned int line_size;
|
struct jpeg_source_mgr source_mgr = { 0, 0,
|
||||||
unsigned char *dstcur;
|
nsjpeg_init_source, nsjpeg_fill_input_buffer,
|
||||||
os_mode_block curr_mode;
|
nsjpeg_skip_input_data, jpeg_resync_to_restart,
|
||||||
|
nsjpeg_term_source };
|
||||||
|
unsigned int height;
|
||||||
|
unsigned int width;
|
||||||
|
unsigned int area_size;
|
||||||
|
osspriteop_area *sprite_area = 0;
|
||||||
|
osspriteop_header *sprite;
|
||||||
|
|
||||||
/* get screenmode (RO3.1 compliant) */
|
cinfo.err = jpeg_std_error(&jerr.pub);
|
||||||
xos_byte(osbyte_SCREEN_CHAR, 0, 0, 0, (int*)&curr_mode);
|
jerr.pub.error_exit = nsjpeg_error_exit;
|
||||||
|
if (setjmp(jerr.setjmp_buffer)) {
|
||||||
|
jpeg_destroy_decompress(&cinfo);
|
||||||
|
free(sprite_area);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
jpeg_create_decompress(&cinfo);
|
||||||
|
source_mgr.next_input_byte = c->source_data;
|
||||||
|
source_mgr.bytes_in_buffer = c->source_size;
|
||||||
|
cinfo.src = &source_mgr;
|
||||||
|
jpeg_read_header(&cinfo, TRUE);
|
||||||
|
cinfo.out_color_space = JCS_RGB;
|
||||||
|
cinfo.dct_method = JDCT_ISLOW;
|
||||||
|
jpeg_start_decompress(&cinfo);
|
||||||
|
|
||||||
/* Try to use OS routines */
|
width = cinfo.output_width;
|
||||||
{
|
height = cinfo.output_height;
|
||||||
os_error *e;
|
|
||||||
int w,h;
|
|
||||||
e = xjpeginfo_dimensions((jpeg_image const*)c->source_data,
|
|
||||||
(int) c->source_size,
|
|
||||||
0, &w, &h, 0, 0, 0);
|
|
||||||
|
|
||||||
if (!e) {
|
area_size = 16 + 44 + width * height * 4;
|
||||||
LOG(("Using inbuilt OS routines"));
|
sprite_area = malloc(area_size);
|
||||||
c->width = w;
|
if (!sprite_area) {
|
||||||
c->height = h;
|
LOG(("malloc failed"));
|
||||||
c->title = xcalloc(100, 1);
|
return 1;
|
||||||
sprintf(c->title, messages_get("JPEGTitle"), w, h, c->source_size);
|
}
|
||||||
c->status = CONTENT_STATUS_DONE;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* failed, for whatever reason -> use jpeglib */
|
|
||||||
c->data.jpeg.use_module = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG(("beginning conversion"));
|
/* area control block */
|
||||||
cinfo.err = jpeg_std_error(&jerr.pub);
|
sprite_area->size = area_size;
|
||||||
jerr.pub.error_exit = nsjpeg_error_exit;
|
sprite_area->sprite_count = 1;
|
||||||
if (setjmp(jerr.setjmp_buffer)) {
|
sprite_area->first = 16;
|
||||||
jpeg_destroy_decompress(&cinfo);
|
sprite_area->used = area_size;
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
jpeg_create_decompress(&cinfo);
|
|
||||||
jpeg_memory_src(&cinfo, c->source_data, c->source_size);
|
|
||||||
jpeg_read_header(&cinfo, TRUE);
|
|
||||||
jpeg_start_decompress(&cinfo);
|
|
||||||
|
|
||||||
c->width = cinfo.output_width;
|
/* sprite control block */
|
||||||
c->height = cinfo.output_height;
|
sprite = (osspriteop_header *) (sprite_area + 1);
|
||||||
line_size = cinfo.output_width*cinfo.output_components;
|
sprite->size = area_size - 16;
|
||||||
|
strncpy(sprite->name, "jpeg", 12);
|
||||||
|
sprite->width = width - 1;
|
||||||
|
sprite->height = height - 1;
|
||||||
|
sprite->left_bit = 0;
|
||||||
|
sprite->right_bit = 31;
|
||||||
|
sprite->image = sprite->mask = 44;
|
||||||
|
sprite->mode = (os_mode) 0x301680b5;
|
||||||
|
|
||||||
LOG(("creating sprite area"));
|
do {
|
||||||
{
|
JSAMPROW scanlines[1];
|
||||||
struct osspriteop_header *spr;
|
scanlines[0] = (JSAMPROW) ((char *) sprite + 44 +
|
||||||
unsigned int abw;
|
width * cinfo.output_scanline * 4);
|
||||||
unsigned int nBytes;
|
jpeg_read_scanlines(&cinfo, scanlines, 1);
|
||||||
|
} while (cinfo.output_scanline != cinfo.output_height);
|
||||||
|
|
||||||
if ((curr_mode.size < 256 && curr_mode.size >= 0) ||
|
jpeg_finish_decompress(&cinfo);
|
||||||
curr_mode.log2_bpp <= 3 /*256*/) {
|
jpeg_destroy_decompress(&cinfo);
|
||||||
abw = ((c->width + 3) &~ 3u) * c->height; /* sprite */
|
|
||||||
nBytes = abw + 44 + 16;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
abw = ((c->width + 3) &~ 3u) * 4 * c->height; /* sprite */
|
|
||||||
nBytes = abw + 44 + 16;
|
|
||||||
}
|
|
||||||
/* nBytes = spr + spr ctrl blk + area ctrl blk */
|
|
||||||
|
|
||||||
c->data.jpeg.sprite_area = xcalloc(1, nBytes);
|
/*xosspriteop_save_sprite_file(osspriteop_USER_AREA,
|
||||||
spr = (osspriteop_header*) (c->data.jpeg.sprite_area + 1);
|
sprite_area, "jpeg");*/
|
||||||
|
|
||||||
/* area control block */
|
c->width = width;
|
||||||
c->data.jpeg.sprite_area->size = nBytes;
|
c->height = height;
|
||||||
c->data.jpeg.sprite_area->sprite_count = 1;
|
c->data.jpeg.sprite_area = sprite_area;
|
||||||
c->data.jpeg.sprite_area->first = sizeof(*c->data.jpeg.sprite_area);
|
c->title = malloc(100);
|
||||||
c->data.jpeg.sprite_area->used = nBytes;
|
if (c->title)
|
||||||
|
sprintf(c->title, messages_get("JPEGTitle"),
|
||||||
/* sprite control block */
|
width, height, c->source_size);
|
||||||
spr->size = nBytes-sizeof(*c->data.jpeg.sprite_area);
|
c->status = CONTENT_STATUS_DONE;
|
||||||
strncpy(spr->name, "jpeg", 12);
|
return 0;
|
||||||
|
|
||||||
if ((curr_mode.size < 256 && curr_mode.size >= 0) ||
|
|
||||||
curr_mode.log2_bpp <= 3 /*256*/) {
|
|
||||||
spr->width = ((c->width+3)>>2)-1; /* in words-1 */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
spr->width = c->width - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
spr->height = c->height-1; /* in scanlines-1 */
|
|
||||||
spr->left_bit = 0;
|
|
||||||
spr->right_bit = ((c->width & 3) * 8 - 1) & 31;
|
|
||||||
spr->image = sizeof(*spr);
|
|
||||||
spr->mask = sizeof(*spr);
|
|
||||||
|
|
||||||
if ((curr_mode.size < 256 && curr_mode.size >= 0) ||
|
|
||||||
curr_mode.log2_bpp <= 3 /*256*/) {
|
|
||||||
spr->mode = os_MODE8BPP90X90; /* 28 */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
spr->mode = (os_mode)((osspriteop_TYPE32BPP<<27) | (90<<14) | (90<<1) | 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
c->data.jpeg.sprite_image = ((char*)spr) + spr->image;
|
|
||||||
|
|
||||||
LOG(("done"));
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG(("processing image: %ldx%ld,%d", c->width, c->height, cinfo.actual_number_of_colors));
|
|
||||||
|
|
||||||
if ((curr_mode.size < 256 && curr_mode.size >= 0) ||
|
|
||||||
curr_mode.log2_bpp <= 3 /*256*/) {
|
|
||||||
JSAMPARRAY buf = (*cinfo.mem->alloc_sarray)
|
|
||||||
((j_common_ptr)&cinfo, JPOOL_IMAGE, line_size, 1);
|
|
||||||
unsigned int col;
|
|
||||||
JSAMPROW row;
|
|
||||||
|
|
||||||
gui_multitask(); /* this takes some time so poll the wimp */
|
|
||||||
while (cinfo.output_scanline < cinfo.output_height) {
|
|
||||||
|
|
||||||
jpeg_read_scanlines(&cinfo, buf, 1);
|
|
||||||
|
|
||||||
row = buf[0];
|
|
||||||
dstcur = c->data.jpeg.sprite_image +
|
|
||||||
cinfo.output_scanline * ((c->width +3) & ~3u);
|
|
||||||
for (col = 0; col != cinfo.output_width; col++) {
|
|
||||||
dstcur[col] = colour_table[((GETJSAMPLE(row[0])>>4)<<8) /* R */
|
|
||||||
| ((GETJSAMPLE(row[1])>>4)<<4) /* G */
|
|
||||||
| (GETJSAMPLE(row[2])>>4)]; /* B */
|
|
||||||
row += 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
JSAMPARRAY buf = (*cinfo.mem->alloc_sarray)
|
|
||||||
((j_common_ptr)&cinfo, JPOOL_IMAGE, line_size, 1);
|
|
||||||
unsigned int col;
|
|
||||||
JSAMPROW row;
|
|
||||||
|
|
||||||
gui_multitask(); /* this takes some time so poll the wimp */
|
|
||||||
dstcur = c->data.jpeg.sprite_image;
|
|
||||||
while (cinfo.output_scanline < cinfo.output_height) {
|
|
||||||
|
|
||||||
jpeg_read_scanlines(&cinfo, buf, 1);
|
|
||||||
|
|
||||||
row = buf[0];
|
|
||||||
for (col = 0; col != cinfo.output_width; col++) {
|
|
||||||
dstcur[0] = GETJSAMPLE(row[0]); /* R */
|
|
||||||
dstcur[1] = GETJSAMPLE(row[1]); /* G */
|
|
||||||
dstcur[2] = GETJSAMPLE(row[2]); /* B */
|
|
||||||
dstcur[3] = 0; /* A */
|
|
||||||
row += 3; dstcur += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jpeg_finish_decompress(&cinfo);
|
|
||||||
jpeg_destroy_decompress(&cinfo);
|
|
||||||
LOG(("image decompressed"));
|
|
||||||
|
|
||||||
/*{
|
|
||||||
os_error *e;
|
|
||||||
e = xosspriteop_save_sprite_file(osspriteop_USER_AREA,
|
|
||||||
c->data.jpeg.sprite_area, "jpeg");
|
|
||||||
}*/
|
|
||||||
|
|
||||||
c->status = CONTENT_STATUS_DONE;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fatal error handler for JPEG library.
|
||||||
|
*
|
||||||
|
* This prevents jpeglib calling exit() on a fatal error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void nsjpeg_error_exit(j_common_ptr cinfo)
|
||||||
|
{
|
||||||
|
struct nsjpeg_error_mgr *err = (struct nsjpeg_error_mgr *) cinfo->err;
|
||||||
|
(*cinfo->err->output_message) (cinfo);
|
||||||
|
longjmp(err->setjmp_buffer, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JPEG data source manager: initialize source.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void nsjpeg_init_source(j_decompress_ptr cinfo)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char nsjpeg_eoi[] = { 0xff, JPEG_EOI };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JPEG data source manager: fill the input buffer.
|
||||||
|
*
|
||||||
|
* This can only occur if the JPEG data was truncated or corrupted. Insert a
|
||||||
|
* fake EOI marker to allow the decompressor to output as much as possible.
|
||||||
|
*/
|
||||||
|
|
||||||
|
boolean nsjpeg_fill_input_buffer(j_decompress_ptr cinfo)
|
||||||
|
{
|
||||||
|
cinfo->src->next_input_byte = nsjpeg_eoi;
|
||||||
|
cinfo->src->bytes_in_buffer = 2;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JPEG data source manager: skip num_bytes worth of data.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void nsjpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
|
||||||
|
{
|
||||||
|
if ((long) cinfo->src->bytes_in_buffer < num_bytes) {
|
||||||
|
cinfo->src->next_input_byte = 0;
|
||||||
|
cinfo->src->bytes_in_buffer = 0;
|
||||||
|
} else {
|
||||||
|
cinfo->src->next_input_byte += num_bytes;
|
||||||
|
cinfo->src->bytes_in_buffer -= num_bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JPEG data source manager: terminate source.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void nsjpeg_term_source(j_decompress_ptr cinfo)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy a CONTENT_JPEG and free all resources it owns.
|
||||||
|
*/
|
||||||
|
|
||||||
void nsjpeg_destroy(struct content *c)
|
void nsjpeg_destroy(struct content *c)
|
||||||
{
|
{
|
||||||
xfree(c->data.jpeg.sprite_area);
|
free(c->data.jpeg.sprite_area);
|
||||||
xfree(c->title);
|
free(c->title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redraw a CONTENT_JPEG.
|
||||||
|
*/
|
||||||
|
|
||||||
void nsjpeg_redraw(struct content *c, long x, long y,
|
void nsjpeg_redraw(struct content *c, long x, long y,
|
||||||
unsigned long width, unsigned long height,
|
unsigned long width, unsigned long height,
|
||||||
long clip_x0, long clip_y0, long clip_x1, long clip_y1,
|
long clip_x0, long clip_y0, long clip_x1, long clip_y1,
|
||||||
float scale)
|
float scale)
|
||||||
{
|
{
|
||||||
unsigned int size;
|
_swix(Tinct_PlotScaled,
|
||||||
osspriteop_trans_tab *table;
|
_IN(2) | _IN(3) | _IN(4) | _IN(5) | _IN(6) | _IN(7),
|
||||||
os_factors factors;
|
(char *) c->data.jpeg.sprite_area +
|
||||||
|
c->data.jpeg.sprite_area->first,
|
||||||
factors.xmul = width;
|
x, (int) (y - height),
|
||||||
factors.ymul = height;
|
width, height,
|
||||||
factors.xdiv = c->width * 2;
|
(option_filter_sprites ? (1<<1) : 0) |
|
||||||
factors.ydiv = c->height * 2;
|
(option_dither_sprites ? (1<<2) : 0));
|
||||||
|
|
||||||
if (c->data.jpeg.use_module) { /* we can use the OS for this one */
|
|
||||||
xjpeg_plot_scaled((jpeg_image *) c->source_data,
|
|
||||||
x, (int)(y - height),
|
|
||||||
&factors, (int) c->source_size,
|
|
||||||
jpeg_SCALE_DITHERED);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
xcolourtrans_generate_table_for_sprite(c->data.jpeg.sprite_area,
|
|
||||||
(osspriteop_id) ((char*)c->data.jpeg.sprite_area +
|
|
||||||
c->data.jpeg.sprite_area->first),
|
|
||||||
colourtrans_CURRENT_MODE, colourtrans_CURRENT_PALETTE,
|
|
||||||
0, colourtrans_GIVEN_SPRITE, 0, 0, &size);
|
|
||||||
|
|
||||||
table = xcalloc(size, 1);
|
|
||||||
|
|
||||||
xcolourtrans_generate_table_for_sprite(c->data.jpeg.sprite_area,
|
|
||||||
(osspriteop_id) ((char*)c->data.jpeg.sprite_area +
|
|
||||||
c->data.jpeg.sprite_area->first),
|
|
||||||
colourtrans_CURRENT_MODE, colourtrans_CURRENT_PALETTE,
|
|
||||||
table, colourtrans_GIVEN_SPRITE, 0, 0, 0);
|
|
||||||
|
|
||||||
xosspriteop_put_sprite_scaled(osspriteop_PTR,
|
|
||||||
c->data.jpeg.sprite_area,
|
|
||||||
(osspriteop_id) ((char*)c->data.jpeg.sprite_area +
|
|
||||||
c->data.jpeg.sprite_area->first),
|
|
||||||
x, (int)(y - height),
|
|
||||||
/* osspriteop_USE_PALETTE is RO 3.5+ only.
|
|
||||||
* behaviour on RO < 3.5 is unknown...
|
|
||||||
*/
|
|
||||||
(osspriteop_action)(osspriteop_USE_MASK |
|
|
||||||
osspriteop_USE_PALETTE),
|
|
||||||
&factors, table);
|
|
||||||
|
|
||||||
xfree(table);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
@ -2,24 +2,20 @@
|
|||||||
* This file is part of NetSurf, http://netsurf.sourceforge.net/
|
* This file is part of NetSurf, http://netsurf.sourceforge.net/
|
||||||
* Licensed under the GNU General Public License,
|
* Licensed under the GNU General Public License,
|
||||||
* http://www.opensource.org/licenses/gpl-license
|
* http://www.opensource.org/licenses/gpl-license
|
||||||
* Copyright 2003 James Bursa <bursa@users.sourceforge.net>
|
* Copyright 2004 James Bursa <bursa@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _NETSURF_RISCOS_JPEG_H_
|
#ifndef _NETSURF_RISCOS_JPEG_H_
|
||||||
#define _NETSURF_RISCOS_JPEG_H_
|
#define _NETSURF_RISCOS_JPEG_H_
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "oslib/osspriteop.h"
|
#include "oslib/osspriteop.h"
|
||||||
|
|
||||||
struct content;
|
struct content;
|
||||||
|
|
||||||
struct content_jpeg_data {
|
struct content_jpeg_data {
|
||||||
osspriteop_area *sprite_area;
|
osspriteop_area *sprite_area;
|
||||||
char *sprite_image;
|
|
||||||
bool use_module;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void nsjpeg_init(void);
|
|
||||||
void nsjpeg_create(struct content *c, const char *params[]);
|
void nsjpeg_create(struct content *c, const char *params[]);
|
||||||
int nsjpeg_convert(struct content *c, unsigned int width, unsigned int height);
|
int nsjpeg_convert(struct content *c, unsigned int width, unsigned int height);
|
||||||
void nsjpeg_destroy(struct content *c);
|
void nsjpeg_destroy(struct content *c);
|
||||||
|
@ -41,8 +41,6 @@ static void add_objects(struct content *content, struct box *box,
|
|||||||
unsigned long cbc, long x, long y);
|
unsigned long cbc, long x, long y);
|
||||||
static void add_graphic(struct content *content, struct box *box,
|
static void add_graphic(struct content *content, struct box *box,
|
||||||
unsigned long cbc, long x, long y);
|
unsigned long cbc, long x, long y);
|
||||||
static void add_jpeg(struct content *content, struct box *box,
|
|
||||||
unsigned long cbc, long x, long y);
|
|
||||||
static void add_rect(struct content *content, struct box *box,
|
static void add_rect(struct content *content, struct box *box,
|
||||||
unsigned long cbc, long x, long y, bool bg);
|
unsigned long cbc, long x, long y, bool bg);
|
||||||
static void add_line(struct content *content, struct box *box,
|
static void add_line(struct content *content, struct box *box,
|
||||||
@ -319,12 +317,7 @@ void add_graphic(struct content *content, struct box *box,
|
|||||||
/* cast-tastic... */
|
/* cast-tastic... */
|
||||||
switch (content->type) {
|
switch (content->type) {
|
||||||
case CONTENT_JPEG:
|
case CONTENT_JPEG:
|
||||||
if (content->data.jpeg.use_module) {
|
sprite_length = ((osspriteop_header*)((char*)content->data.jpeg.sprite_area+content->data.jpeg.sprite_area->first))->size;
|
||||||
sprite_length = -1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sprite_length = ((osspriteop_header*)((char*)content->data.jpeg.sprite_area+content->data.jpeg.sprite_area->first))->size;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case CONTENT_PNG:
|
case CONTENT_PNG:
|
||||||
sprite_length = ((osspriteop_header*)((char*)content->data.png.sprite_area+content->data.png.sprite_area->first))->size;
|
sprite_length = ((osspriteop_header*)((char*)content->data.png.sprite_area+content->data.png.sprite_area->first))->size;
|
||||||
@ -339,11 +332,6 @@ void add_graphic(struct content *content, struct box *box,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sprite_length == -1 && content->type == CONTENT_JPEG) {
|
|
||||||
add_jpeg(content, box, cbc, x, y);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dro = xcalloc((unsigned)8 + 16 + sprite_length, sizeof(char));
|
dro = xcalloc((unsigned)8 + 16 + sprite_length, sizeof(char));
|
||||||
ds = xcalloc((unsigned)16 + sprite_length, sizeof(char));
|
ds = xcalloc((unsigned)16 + sprite_length, sizeof(char));
|
||||||
|
|
||||||
@ -387,54 +375,6 @@ void add_graphic(struct content *content, struct box *box,
|
|||||||
xfree(dro);
|
xfree(dro);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add jpeg objects which the OS can cope with.
|
|
||||||
* Jpegs the OS doesn't understand are added as sprites
|
|
||||||
* This may still be a little buggy.
|
|
||||||
*/
|
|
||||||
void add_jpeg(struct content *content, struct box *box,
|
|
||||||
unsigned long cbc, long x, long y) {
|
|
||||||
|
|
||||||
drawfile_object *dro = xcalloc(8+60+((content->source_size+3)/4*4), sizeof(char));
|
|
||||||
drawfile_jpeg *dj = xcalloc(60+((content->source_size+3)/4*4), sizeof(char));
|
|
||||||
int flags;
|
|
||||||
|
|
||||||
dj->bbox.x0 = x+(box->padding[LEFT]*512);
|
|
||||||
dj->bbox.y0 = y-((box->padding[TOP] + box->height)*512);
|
|
||||||
dj->bbox.x1 = x+((box->padding[LEFT] + box->width)*512);
|
|
||||||
dj->bbox.y1 = y-(box->padding[TOP]*512);
|
|
||||||
|
|
||||||
xjpeginfo_dimensions((jpeg_image const*)content->source_data,
|
|
||||||
(int)content->source_size,
|
|
||||||
&flags, &dj->width, &dj->height,
|
|
||||||
&dj->xdpi, &dj->ydpi, 0);
|
|
||||||
dj->width *= 512;
|
|
||||||
dj->height *= 512;
|
|
||||||
if (flags & 4) { /* pixel density is a ratio */
|
|
||||||
dj->ydpi = 90 * (dj->ydpi / dj->xdpi);
|
|
||||||
dj->xdpi = 90;
|
|
||||||
}
|
|
||||||
dj->trfm.entries[0][0] = (dj->width*256) / ((dj->bbox.x1-dj->bbox.x0)/256);
|
|
||||||
dj->trfm.entries[0][1] = 0;
|
|
||||||
dj->trfm.entries[1][0] = 0;
|
|
||||||
dj->trfm.entries[1][1] = (dj->height*256) / ((dj->bbox.y1-dj->bbox.y0)/256);
|
|
||||||
dj->trfm.entries[2][0] = dj->bbox.x0;
|
|
||||||
dj->trfm.entries[2][1] = dj->bbox.y0;
|
|
||||||
dj->len = content->source_size;
|
|
||||||
memcpy((char*)&dj->image, content->source_data, (unsigned)dj->len);
|
|
||||||
|
|
||||||
dro->type = drawfile_TYPE_JPEG;
|
|
||||||
dro->size = 8 + 60 + ((dj->len+3)/4*4);
|
|
||||||
memcpy((char*)&dro->data.jpeg, dj, (unsigned)dro->size-8);
|
|
||||||
|
|
||||||
d = xrealloc(d, length+dro->size);
|
|
||||||
memcpy((char*)d+length, dro, (unsigned)dro->size);
|
|
||||||
|
|
||||||
length += dro->size;
|
|
||||||
|
|
||||||
xfree(dj);
|
|
||||||
xfree(dro);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a filled, borderless rectangle to the diagram
|
* Add a filled, borderless rectangle to the diagram
|
||||||
|
Loading…
Reference in New Issue
Block a user