[project @ 2006-02-26 02:25:19 by rjw]
Add support for ICO files. svn path=/import/netsurf/; revision=2096
This commit is contained in:
parent
da4a9313f1
commit
60ea34ad48
|
@ -326,6 +326,7 @@ SelectMenu:Select
|
|||
DrawTitle:Draw Bild (%lux%lu, %lu bytes)
|
||||
GIFTitle:GIF Bild (%lux%lu, %lu bytes)
|
||||
BMPTitle:BMP Bild (%lux%lu, %lu bytes)
|
||||
ICOTitle:ICO Bild (%lux%lu, %lu bytes)
|
||||
JPEGTitle:JPEG Bild (%ux%u, %lu bytes)
|
||||
PNGTitle:PNG Bild (%lux%lu, %lu bytes)
|
||||
JNGTitle:JNG Bild (%lux%lu, %lu bytes)
|
||||
|
@ -438,6 +439,7 @@ ObjError:Error loading object: %s
|
|||
ParsingFail:Parsing the document failed.
|
||||
BadGIF:Reading GIF failed.
|
||||
BadBMP:Reading BMP failed.
|
||||
BadICO:Reading ICO failed.
|
||||
PNGError:PNG library error.
|
||||
MNGError:MNG library error.
|
||||
BadSprite:Invalid or corrupt Sprite data.
|
||||
|
|
|
@ -326,6 +326,7 @@ SelectMenu:Select
|
|||
DrawTitle:Draw image (%lux%lu, %lu bytes)
|
||||
GIFTitle:GIF image (%lux%lu, %lu bytes)
|
||||
BMPTitle:BMP image (%lux%lu, %lu bytes)
|
||||
ICOTitle:ICO image (%lux%lu, %lu bytes)
|
||||
JPEGTitle:JPEG image (%ux%u, %lu bytes)
|
||||
PNGTitle:PNG image (%lux%lu, %lu bytes)
|
||||
JNGTitle:JNG image (%lux%lu, %lu bytes)
|
||||
|
@ -437,6 +438,7 @@ ObjError:Error loading object: %s
|
|||
ParsingFail:Parsing the document failed.
|
||||
BadGIF:Reading GIF failed.
|
||||
BadBMP:Reading BMP failed.
|
||||
BadICO:Reading ICO failed.
|
||||
PNGError:PNG library error.
|
||||
MNGError:MNG library error.
|
||||
BadSprite:Invalid or corrupt Sprite data.
|
||||
|
|
|
@ -326,6 +326,7 @@ SelectMenu:Sélection
|
|||
DrawTitle:Image Draw (%lux%lu, %lu octets)
|
||||
GIFTitle:Image GIF (%lux%lu, %lu octets)
|
||||
BMPTitle:Image BMP (%lux%lu, %lu octets)
|
||||
ICOTitle:Image BMP (%lux%lu, %lu octets)
|
||||
JPEGTitle:Image JPEG (%ux%u, %lu octets)
|
||||
PNGTitle:Image PNG (%lux%lu, %lu octets)
|
||||
JNGTitle:Image JNG (%lux%lu, %lu octets)
|
||||
|
@ -438,6 +439,7 @@ ObjError:Erreur lors du chargement de: %s
|
|||
ParsingFail:L'analyse syntaxique du document a échoué.
|
||||
BadGIF:Erreur de lecture de GIF.
|
||||
BadBMP:Erreur de lecture de BMP.
|
||||
BadICO:Erreur de lecture de ICO.
|
||||
PNGError:Erreur dans la bibliothèque PNG.
|
||||
MNGError:Erreur dans la bibliothèque MNG.
|
||||
BadSprite:Les données du sprite sont invalides ou corrompues.
|
||||
|
|
|
@ -327,6 +327,7 @@ SelectMenu:Select
|
|||
DrawTitle:Draw image (%lux%lu, %lu bytes)
|
||||
GIFTitle:GIF image (%lux%lu, %lu bytes)
|
||||
BMPTitle:BMP image (%lux%lu, %lu bytes)
|
||||
ICOTitle:ICO image (%lux%lu, %lu bytes)
|
||||
JPEGTitle:JPEG image (%ux%u, %lu bytes)
|
||||
PNGTitle:PNG image (%lux%lu, %lu bytes)
|
||||
JNGTitle:JNG image (%lux%lu, %lu bytes)
|
||||
|
@ -440,6 +441,7 @@ ObjError:fout bij laden object: %s
|
|||
ParsingFail:fout bij ontleden van dit document.
|
||||
BadGIF:fout bij lezen GIF.
|
||||
BadBMP:fout bij lezen BMP.
|
||||
BadICO:fout bij lezen ICO.
|
||||
PNGError:PNG library fout.
|
||||
MNGError:MNG library fout.
|
||||
BadSprite:foutief sprite bestand.
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#endif
|
||||
#ifdef WITH_BMP
|
||||
#include "netsurf/image/bmp.h"
|
||||
#include "netsurf/image/ico.h"
|
||||
#endif
|
||||
#ifdef WITH_SPRITE
|
||||
#include "netsurf/riscos/sprite.h"
|
||||
|
@ -78,12 +79,16 @@ static const struct mime_entry mime_map[] = {
|
|||
{"application/drawfile", CONTENT_DRAW},
|
||||
#endif
|
||||
#ifdef WITH_BMP
|
||||
{"application/ico", CONTENT_ICO},
|
||||
{"application/preview", CONTENT_BMP},
|
||||
{"application/x-bmp", CONTENT_BMP},
|
||||
#endif
|
||||
#ifdef WITH_DRAW
|
||||
{"application/x-drawfile", CONTENT_DRAW},
|
||||
#endif
|
||||
#ifdef WITH_BMP
|
||||
{"application/x-ico", CONTENT_ICO},
|
||||
#endif
|
||||
#ifdef WITH_THEME_INSTALL
|
||||
{"application/x-netsurf-theme", CONTENT_THEME},
|
||||
#endif
|
||||
|
@ -103,6 +108,9 @@ static const struct mime_entry mime_map[] = {
|
|||
#ifdef WITH_GIF
|
||||
{"image/gif", CONTENT_GIF},
|
||||
#endif
|
||||
#ifdef WITH_BMP
|
||||
{"image/ico", CONTENT_ICO},
|
||||
#endif
|
||||
#ifdef WITH_MNG
|
||||
{"image/jng", CONTENT_JNG},
|
||||
#endif
|
||||
|
@ -128,6 +136,9 @@ static const struct mime_entry mime_map[] = {
|
|||
#ifdef WITH_DRAW
|
||||
{"image/x-drawfile", CONTENT_DRAW},
|
||||
#endif
|
||||
#ifdef WITH_BMP
|
||||
{"image/x-icon", CONTENT_ICO},
|
||||
#endif
|
||||
#ifdef WITH_MNG
|
||||
{"image/x-jng", CONTENT_JNG},
|
||||
{"image/x-mng", CONTENT_MNG},
|
||||
|
@ -165,6 +176,7 @@ const char *content_type_name[] = {
|
|||
#endif
|
||||
#ifdef WITH_BMP
|
||||
"BMP",
|
||||
"ICO",
|
||||
#endif
|
||||
#ifdef WITH_MNG
|
||||
"PNG",
|
||||
|
@ -245,6 +257,8 @@ static const struct handler_entry handler_map[] = {
|
|||
#ifdef WITH_BMP
|
||||
{nsbmp_create, 0, nsbmp_convert, 0, nsbmp_destroy, 0,
|
||||
nsbmp_redraw, nsbmp_redraw_tiled, 0, 0, false},
|
||||
{nsico_create, 0, nsico_convert, 0, nsico_destroy, 0,
|
||||
nsico_redraw, nsico_redraw_tiled, 0, 0, false},
|
||||
#endif
|
||||
#ifdef WITH_MNG
|
||||
{nsmng_create, nsmng_process_data, nsmng_convert,
|
||||
|
|
|
@ -117,6 +117,7 @@
|
|||
#endif
|
||||
#ifdef WITH_BMP
|
||||
#include "netsurf/image/bmp.h"
|
||||
#include "netsurf/image/ico.h"
|
||||
#endif
|
||||
#ifdef WITH_PLUGIN
|
||||
#include "netsurf/riscos/plugin.h"
|
||||
|
@ -235,6 +236,7 @@ struct content {
|
|||
#endif
|
||||
#ifdef WITH_BMP
|
||||
struct content_bmp_data bmp;
|
||||
struct content_ico_data ico;
|
||||
#endif
|
||||
#ifdef WITH_MNG
|
||||
struct content_mng_data mng;
|
||||
|
|
|
@ -30,6 +30,7 @@ typedef enum {
|
|||
#endif
|
||||
#ifdef WITH_BMP
|
||||
CONTENT_BMP,
|
||||
CONTENT_ICO,
|
||||
#endif
|
||||
#ifdef WITH_MNG
|
||||
CONTENT_PNG,
|
||||
|
|
12
image/bmp.c
12
image/bmp.c
|
@ -11,8 +11,6 @@
|
|||
#include <stdlib.h>
|
||||
#include "netsurf/utils/config.h"
|
||||
#include "netsurf/content/content.h"
|
||||
#include "netsurf/desktop/browser.h"
|
||||
#include "netsurf/desktop/options.h"
|
||||
#include "netsurf/desktop/plotters.h"
|
||||
#include "netsurf/image/bitmap.h"
|
||||
#include "netsurf/image/bmp.h"
|
||||
|
@ -23,8 +21,6 @@
|
|||
|
||||
#ifdef WITH_BMP
|
||||
|
||||
static void nsbmp_invalidate(struct bitmap *bitmap, void *private_word);
|
||||
|
||||
bool nsbmp_create(struct content *c, const char *params[]) {
|
||||
union content_msg_data msg_data;
|
||||
|
||||
|
@ -76,20 +72,12 @@ bool nsbmp_convert(struct content *c, int iwidth, int iheight) {
|
|||
c->height, c->source_size);
|
||||
c->size += (bmp->width * bmp->height * 4) + 16 + 44 + 100;
|
||||
|
||||
/* make so that the bitmap code can free our image quickly */
|
||||
bitmap_set_suspendable(bmp->bitmap, bmp, nsbmp_invalidate);
|
||||
|
||||
/* exit as a success */
|
||||
c->bitmap = bmp->bitmap;
|
||||
c->status = CONTENT_STATUS_DONE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void nsbmp_invalidate(struct bitmap *bitmap, void *private_word) {
|
||||
struct bmp_image *bmp = (struct bmp_image *)private_word;
|
||||
|
||||
bmp->decoded = false;
|
||||
}
|
||||
|
||||
bool nsbmp_redraw(struct content *c, int x, int y,
|
||||
int width, int height,
|
||||
|
|
272
image/bmpread.c
272
image/bmpread.c
|
@ -18,9 +18,12 @@
|
|||
#define READ_SHORT(a, o) (a[o]|(a[o+1]<<8))
|
||||
#define READ_INT(a, o) (a[o]|(a[o+1]<<8)|(a[o+2]<<16)|(a[o+3]<<24))
|
||||
|
||||
bmp_result bmp_decode_rgb24(struct bmp_image *bmp, char *data, int bytes);
|
||||
bmp_result bmp_decode_rgb(struct bmp_image *bmp, char *data, int bytes);
|
||||
bmp_result bmp_analyse_header(struct bmp_image *bmp, char *data);
|
||||
bmp_result bmp_decode_rgb24(struct bmp_image *bmp, char **start, int bytes);
|
||||
bmp_result bmp_decode_rgb(struct bmp_image *bmp, char **start, int bytes);
|
||||
bmp_result bmp_decode_mask(struct bmp_image *bmp, char *data, int bytes);
|
||||
bmp_result bmp_decode_rle(struct bmp_image *bmp, char *data, int bytes, int size);
|
||||
void bmp_invalidate(struct bitmap *bitmap, void *private_word);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -37,10 +40,6 @@ bmp_result bmp_decode_rle(struct bmp_image *bmp, char *data, int bytes, int size
|
|||
*/
|
||||
bmp_result bmp_analyse(struct bmp_image *bmp) {
|
||||
char *data = bmp->bmp_data;
|
||||
unsigned int header_size;
|
||||
unsigned int i;
|
||||
int width, height;
|
||||
int palette_size;
|
||||
|
||||
/* ensure we aren't already initialised */
|
||||
if (bmp->bitmap)
|
||||
|
@ -59,9 +58,85 @@ bmp_result bmp_analyse(struct bmp_image *bmp) {
|
|||
if ((data[0] != 'B') || (data[1] != 'M'))
|
||||
return BMP_DATA_ERROR;
|
||||
bmp->bitmap_offset = READ_INT(data, 10);
|
||||
data += 14;
|
||||
|
||||
/* decode the BMP header */
|
||||
return bmp_analyse_header(bmp, data + 14);
|
||||
}
|
||||
|
||||
|
||||
/* a variety of different bitmap headers can now follow, depending
|
||||
/**
|
||||
* Analyse an ICO prior to decoding.
|
||||
*
|
||||
* This function will scan the data provided and perform simple checks to
|
||||
* ensure the data is a valid ICO.
|
||||
*
|
||||
* This function must be called before ico_find().
|
||||
*
|
||||
* \param ico the ICO image to analyse
|
||||
* \return BMP_OK on success
|
||||
*/
|
||||
bmp_result ico_analyse(struct ico_collection *ico) {
|
||||
char *data = ico->ico_data;
|
||||
unsigned int count, i;
|
||||
bmp_result result;
|
||||
struct ico_image *image;
|
||||
int area, max_area = 0;
|
||||
|
||||
/* ensure we aren't already initialised */
|
||||
if (ico->first)
|
||||
return BMP_OK;
|
||||
|
||||
/* standard 6-byte ICO file header is:
|
||||
*
|
||||
* +0 INT 0x00010000
|
||||
* +4 SHORT number of BMPs to follow
|
||||
*/
|
||||
if (ico->buffer_size < 6)
|
||||
return BMP_INSUFFICIENT_DATA;
|
||||
if (READ_INT(data, 0) != 0x00010000)
|
||||
return BMP_DATA_ERROR;
|
||||
count = READ_SHORT(data, 4);
|
||||
if (count == 0)
|
||||
return BMP_DATA_ERROR;
|
||||
data += 6;
|
||||
|
||||
/* decode the BMP files */
|
||||
if (ico->buffer_size < 6 + (16 * count))
|
||||
return BMP_INSUFFICIENT_DATA;
|
||||
for (i = 0; i < count; i++) {
|
||||
image = calloc(1, sizeof(struct ico_image));
|
||||
if (!image)
|
||||
return BMP_INSUFFICIENT_MEMORY;
|
||||
image->next = ico->first;
|
||||
ico->first = image;
|
||||
image->bmp.width = data[0];
|
||||
image->bmp.height = data[1];
|
||||
image->bmp.buffer_size = READ_INT(data, 8) + 40;
|
||||
image->bmp.bmp_data = ico->ico_data + READ_INT(data, 12);
|
||||
image->bmp.ico = true;
|
||||
data += 16;
|
||||
result = bmp_analyse_header(&image->bmp, image->bmp.bmp_data);
|
||||
if (result != BMP_OK)
|
||||
return result;
|
||||
area = image->bmp.width * image->bmp.height;
|
||||
if (area > max_area) {
|
||||
ico->width = image->bmp.width;
|
||||
ico->height = image->bmp.height;
|
||||
max_area = area;
|
||||
}
|
||||
}
|
||||
return BMP_OK;
|
||||
}
|
||||
|
||||
|
||||
bmp_result bmp_analyse_header(struct bmp_image *bmp, char *data) {
|
||||
unsigned int header_size;
|
||||
unsigned int i;
|
||||
int width, height;
|
||||
int palette_size;
|
||||
unsigned int flags;
|
||||
|
||||
/* a variety of different bitmap headers can follow, depending
|
||||
* on the BMP variant. A full description of the various headers
|
||||
* can be found at http://www.fileformat.info/format/bmp/
|
||||
*/
|
||||
|
@ -127,19 +202,23 @@ bmp_result bmp_analyse(struct bmp_image *bmp) {
|
|||
* +100 INT gamma green coordinate scale value
|
||||
* +104 INT gamma blue coordinate scale value
|
||||
*/
|
||||
width = READ_INT(data, 4);
|
||||
height = READ_INT(data, 8);
|
||||
if (width < 0)
|
||||
return BMP_DATA_ERROR;
|
||||
if (height < 0) {
|
||||
bmp->reversed = true;
|
||||
height = -height;
|
||||
if (!bmp->ico) {
|
||||
width = READ_INT(data, 4);
|
||||
height = READ_INT(data, 8);
|
||||
if (width < 0)
|
||||
return BMP_DATA_ERROR;
|
||||
if (height < 0) {
|
||||
bmp->reversed = true;
|
||||
height = -height;
|
||||
}
|
||||
bmp->width = width;
|
||||
bmp->height = height;
|
||||
}
|
||||
bmp->width = width;
|
||||
bmp->height = height;
|
||||
if (READ_SHORT(data, 12) != 1)
|
||||
return BMP_DATA_ERROR;
|
||||
bmp->bpp = READ_SHORT(data, 14);
|
||||
if (bmp->bpp == 0)
|
||||
bmp->bpp = 8;
|
||||
bmp->encoding = READ_INT(data, 16);
|
||||
if (bmp->encoding >= BMP_ENCODING_BITFIELDS) /* unsupported so far */
|
||||
return BMP_DATA_ERROR;
|
||||
|
@ -169,25 +248,74 @@ bmp_result bmp_analyse(struct bmp_image *bmp) {
|
|||
if (!bmp->colour_table)
|
||||
return BMP_INSUFFICIENT_MEMORY;
|
||||
for (i = 0; i < bmp->colours; i++) {
|
||||
bmp->colour_table[i] = (data[2] | (data[1] << 8) |
|
||||
(data[0] << 16) | (0xff << 24));
|
||||
bmp->colour_table[i] = data[2] | (data[1] << 8) |
|
||||
(data[0] << 16);
|
||||
data += palette_size;
|
||||
}
|
||||
}
|
||||
|
||||
/* create our bitmap */
|
||||
bmp->bitmap = bitmap_create(bmp->width, bmp->height,
|
||||
BITMAP_NEW | BITMAP_OPAQUE | BITMAP_CLEAR_MEMORY);
|
||||
flags = BITMAP_NEW | BITMAP_CLEAR_MEMORY;
|
||||
if (!bmp->ico)
|
||||
flags |= BITMAP_OPAQUE;
|
||||
bmp->bitmap = bitmap_create(bmp->width, bmp->height, flags);
|
||||
if (!bmp->bitmap) {
|
||||
if (bmp->colour_table)
|
||||
free(bmp->colour_table);
|
||||
bmp->colour_table = NULL;
|
||||
return BMP_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
bmp->bitmap_offset = (int)data - (int)bmp->bmp_data;
|
||||
bitmap_set_suspendable(bmp->bitmap, bmp, bmp_invalidate);
|
||||
return BMP_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Finds the closest BMP within an ICO collection
|
||||
*
|
||||
* This function finds the BMP with dimensions as close to a specified set
|
||||
* as possible from the images in the collection.
|
||||
*
|
||||
* \param ico the ICO collection to examine
|
||||
* \param width the preferred width
|
||||
* \param height the preferred height
|
||||
*/
|
||||
struct bmp_image *ico_find(struct ico_collection *ico, int width, int height) {
|
||||
struct bmp_image *bmp = NULL;
|
||||
struct ico_image *image;
|
||||
int x, y, cur, distance = (1 << 24);
|
||||
|
||||
for (image = ico->first; image; image = image->next) {
|
||||
if (((int)image->bmp.width == width) && ((int)image->bmp.height == height))
|
||||
return &image->bmp;
|
||||
x = image->bmp.width - width;
|
||||
y = image->bmp.height - height;
|
||||
cur = (x * x) + (y * y);
|
||||
if (cur < distance) {
|
||||
distance = cur;
|
||||
bmp = &image->bmp;
|
||||
}
|
||||
}
|
||||
return bmp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Invalidates a BMP
|
||||
*
|
||||
* This function sets the BMP into a state such that the bitmap image data
|
||||
* can be released from memory.
|
||||
*
|
||||
* \param bmp the BMP image to invalidate
|
||||
*/
|
||||
void bmp_invalidate(struct bitmap *bitmap, void *private_word) {
|
||||
struct bmp_image *bmp = (struct bmp_image *)private_word;
|
||||
|
||||
bmp->decoded = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decode a BMP
|
||||
*
|
||||
|
@ -201,6 +329,7 @@ bmp_result bmp_analyse(struct bmp_image *bmp) {
|
|||
bmp_result bmp_decode(struct bmp_image *bmp) {
|
||||
char *data;
|
||||
int bytes;
|
||||
bmp_result result = BMP_OK;
|
||||
|
||||
assert(bmp->bitmap);
|
||||
|
||||
|
@ -210,20 +339,27 @@ bmp_result bmp_decode(struct bmp_image *bmp) {
|
|||
switch (bmp->encoding) {
|
||||
case BMP_ENCODING_RGB:
|
||||
if (bmp->bpp >= 24)
|
||||
return bmp_decode_rgb24(bmp, data, bytes);
|
||||
result = bmp_decode_rgb24(bmp, &data, bytes);
|
||||
else if (bmp->bpp > 8)
|
||||
return BMP_DATA_ERROR;
|
||||
else
|
||||
return bmp_decode_rgb(bmp, data, bytes);
|
||||
case BMP_ENCODING_RLE8:
|
||||
return bmp_decode_rle(bmp, data, bytes, 8);
|
||||
case BMP_ENCODING_RLE4:
|
||||
return bmp_decode_rle(bmp, data, bytes, 4);
|
||||
case BMP_ENCODING_BITFIELDS:
|
||||
/* todo: implement me */
|
||||
result = bmp_decode_rgb(bmp, &data, bytes);
|
||||
break;
|
||||
case BMP_ENCODING_RLE8:
|
||||
result = bmp_decode_rle(bmp, data, bytes, 8);
|
||||
break;
|
||||
case BMP_ENCODING_RLE4:
|
||||
result = bmp_decode_rle(bmp, data, bytes, 4);
|
||||
break;
|
||||
case BMP_ENCODING_BITFIELDS:
|
||||
return BMP_DATA_ERROR;
|
||||
}
|
||||
return BMP_DATA_ERROR;
|
||||
|
||||
if ((!bmp->ico) || (result != BMP_OK))
|
||||
return result;
|
||||
|
||||
bytes = (int)bmp->bmp_data + bmp->buffer_size - (int)data;
|
||||
return bmp_decode_mask(bmp, data, bytes);
|
||||
}
|
||||
|
||||
|
||||
|
@ -231,16 +367,17 @@ bmp_result bmp_decode(struct bmp_image *bmp) {
|
|||
* Decode BMP data stored in 24bpp colour.
|
||||
*
|
||||
* \param bmp the BMP image to decode
|
||||
* \param data the data to decode
|
||||
* \param start the data to decode, updated to last byte read on success
|
||||
* \param bytes the number of bytes of data available
|
||||
* \return BMP_OK on success
|
||||
*/
|
||||
bmp_result bmp_decode_rgb24(struct bmp_image *bmp, char *data, int bytes) {
|
||||
char *top, *bottom, *end;
|
||||
bmp_result bmp_decode_rgb24(struct bmp_image *bmp, char **start, int bytes) {
|
||||
char *top, *bottom, *end, *data;
|
||||
unsigned int *scanline;
|
||||
unsigned int x, y, swidth, skip;
|
||||
unsigned int addr;
|
||||
|
||||
data = *start;
|
||||
swidth = bitmap_get_rowstride(bmp->bitmap);
|
||||
top = bitmap_get_buffer(bmp->bitmap);
|
||||
bottom = top + swidth * (bmp->height - 1);
|
||||
|
@ -263,6 +400,7 @@ bmp_result bmp_decode_rgb24(struct bmp_image *bmp, char *data, int bytes) {
|
|||
data += skip;
|
||||
}
|
||||
}
|
||||
*start = data;
|
||||
return BMP_OK;
|
||||
}
|
||||
|
||||
|
@ -271,12 +409,12 @@ bmp_result bmp_decode_rgb24(struct bmp_image *bmp, char *data, int bytes) {
|
|||
* Decode BMP data stored with a palette and in 8bpp colour or less.
|
||||
*
|
||||
* \param bmp the BMP image to decode
|
||||
* \param data the data to decode
|
||||
* \param start the data to decode, updated to last byte read on success
|
||||
* \param bytes the number of bytes of data available
|
||||
* \return BMP_OK on success
|
||||
*/
|
||||
bmp_result bmp_decode_rgb(struct bmp_image *bmp, char *data, int bytes) {
|
||||
char *top, *bottom, *end;
|
||||
bmp_result bmp_decode_rgb(struct bmp_image *bmp, char **start, int bytes) {
|
||||
char *top, *bottom, *end, *data;
|
||||
unsigned int *scanline;
|
||||
unsigned int addr;
|
||||
unsigned int x, y, swidth;
|
||||
|
@ -289,6 +427,7 @@ bmp_result bmp_decode_rgb(struct bmp_image *bmp, char *data, int bytes) {
|
|||
for (i = 0; i < ppb; i++)
|
||||
bit_shifts[i] = 8 - ((i + 1) * bmp->bpp);
|
||||
|
||||
data = *start;
|
||||
swidth = bitmap_get_rowstride(bmp->bitmap);
|
||||
top = bitmap_get_buffer(bmp->bitmap);
|
||||
bottom = top + swidth * (bmp->height - 1);
|
||||
|
@ -315,6 +454,46 @@ bmp_result bmp_decode_rgb(struct bmp_image *bmp, char *data, int bytes) {
|
|||
bit_shifts[bit++]) & bit_mask];
|
||||
}
|
||||
}
|
||||
*start = data;
|
||||
return BMP_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decode a 1bpp mask for an ICO
|
||||
*
|
||||
* \param bmp the BMP image to decode
|
||||
* \param data the data to decode
|
||||
* \param bytes the number of bytes of data available
|
||||
* \return BMP_OK on success
|
||||
*/
|
||||
bmp_result bmp_decode_mask(struct bmp_image *bmp, char *data, int bytes) {
|
||||
char *top, *bottom, *end;
|
||||
unsigned int *scanline;
|
||||
unsigned int addr;
|
||||
unsigned int x, y, swidth;
|
||||
int cur_byte = 0;
|
||||
|
||||
swidth = bitmap_get_rowstride(bmp->bitmap);
|
||||
top = bitmap_get_buffer(bmp->bitmap);
|
||||
bottom = top + swidth * (bmp->height - 1);
|
||||
end = data + bytes;
|
||||
addr = ((unsigned int)data) & 3;
|
||||
|
||||
for (y = 0; y < bmp->height; y++) {
|
||||
while (addr != (((unsigned int)data) & 3))
|
||||
data++;
|
||||
if ((data + (bmp->width >> 3)) > end)
|
||||
return BMP_INSUFFICIENT_DATA;
|
||||
scanline = (unsigned int *)(bottom - (y * swidth));
|
||||
for (x = 0; x < bmp->width; x++) {
|
||||
if ((x & 7) == 0)
|
||||
cur_byte = *data++;
|
||||
if ((cur_byte & 128) == 0)
|
||||
scanline[x] |= (0xff << 24);
|
||||
cur_byte = cur_byte << 1;
|
||||
}
|
||||
}
|
||||
return BMP_OK;
|
||||
}
|
||||
|
||||
|
@ -336,6 +515,9 @@ bmp_result bmp_decode_rle(struct bmp_image *bmp, char *data, int bytes, int size
|
|||
unsigned int x = 0, y = 0, last_y = 0;
|
||||
unsigned int pixel = 0, pixel2;
|
||||
|
||||
if (bmp->ico)
|
||||
return BMP_DATA_ERROR;
|
||||
|
||||
swidth = bitmap_get_rowstride(bmp->bitmap);
|
||||
top = bitmap_get_buffer(bmp->bitmap);
|
||||
bottom = top + swidth * (bmp->height - 1);
|
||||
|
@ -481,3 +663,21 @@ void bmp_finalise(struct bmp_image *bmp) {
|
|||
free(bmp->colour_table);
|
||||
bmp->colour_table = NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finalise an ICO prior to destruction.
|
||||
*
|
||||
* \param ico the ICO image to finalise
|
||||
*/
|
||||
void ico_finalise(struct ico_collection *ico) {
|
||||
struct ico_image *image;
|
||||
|
||||
for (image = ico->first; image; image = image->next)
|
||||
bmp_finalise(&image->bmp);
|
||||
while (ico->first) {
|
||||
image = ico->first;
|
||||
ico->first = image->next;
|
||||
free(image);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,11 +44,29 @@ struct bmp_image {
|
|||
unsigned int *colour_table; /** colour table */
|
||||
bool reversed; /** scanlines are top to bottom */
|
||||
bool decoded; /** whether the image has been decoded */
|
||||
bool ico; /** image is part of an ICO, mask follows */
|
||||
struct bitmap *bitmap; /** decoded image */
|
||||
};
|
||||
|
||||
struct ico_image {
|
||||
struct bmp_image bmp;
|
||||
struct ico_image *next;
|
||||
};
|
||||
|
||||
struct ico_collection {
|
||||
unsigned char *ico_data; /** pointer to ICO data */
|
||||
unsigned int buffer_size; /** total number of bytes of ICO data available */
|
||||
unsigned int width; /** width of largest BMP */
|
||||
unsigned int height; /** heigth of largest BMP */
|
||||
struct ico_image *first;
|
||||
};
|
||||
|
||||
bmp_result bmp_analyse(struct bmp_image *bmp);
|
||||
bmp_result bmp_decode(struct bmp_image *bmp);
|
||||
void bmp_finalise(struct bmp_image *bmp);
|
||||
|
||||
bmp_result ico_analyse(struct ico_collection *ico);
|
||||
struct bmp_image *ico_find(struct ico_collection *ico, int width, int height);
|
||||
void ico_finalise(struct ico_collection *ico);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* This file is part of NetSurf, http://netsurf.sourceforge.net/
|
||||
* Licensed under the GNU General Public License,
|
||||
* http://www.opensource.org/licenses/gpl-license
|
||||
* Copyright 2006 Richard Wilson <info@tinct.net>
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "netsurf/utils/config.h"
|
||||
#include "netsurf/content/content.h"
|
||||
#include "netsurf/desktop/plotters.h"
|
||||
#include "netsurf/image/bitmap.h"
|
||||
#include "netsurf/image/bmpread.h"
|
||||
#include "netsurf/image/ico.h"
|
||||
#include "netsurf/utils/log.h"
|
||||
#include "netsurf/utils/messages.h"
|
||||
#include "netsurf/utils/utils.h"
|
||||
|
||||
#ifdef WITH_BMP
|
||||
|
||||
bool nsico_create(struct content *c, const char *params[]) {
|
||||
union content_msg_data msg_data;
|
||||
|
||||
c->data.ico.ico = calloc(sizeof(struct ico_collection), 1);
|
||||
if (!c->data.ico.ico) {
|
||||
msg_data.error = messages_get("NoMemory");
|
||||
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool nsico_convert(struct content *c, int iwidth, int iheight) {
|
||||
struct bmp_image *bmp;
|
||||
bmp_result res;
|
||||
struct ico_collection *ico;
|
||||
union content_msg_data msg_data;
|
||||
|
||||
/* set our source data */
|
||||
ico = c->data.ico.ico;
|
||||
ico->ico_data = c->source_data;
|
||||
ico->buffer_size = c->source_size;
|
||||
|
||||
/* analyse the BMP */
|
||||
res = ico_analyse(ico);
|
||||
switch (res) {
|
||||
case BMP_OK:
|
||||
break;
|
||||
case BMP_INSUFFICIENT_MEMORY:
|
||||
msg_data.error = messages_get("NoMemory");
|
||||
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
case BMP_INSUFFICIENT_DATA:
|
||||
case BMP_DATA_ERROR:
|
||||
msg_data.error = messages_get("BadICO");
|
||||
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Store our content width and description
|
||||
*/
|
||||
c->width = ico->width;
|
||||
c->height = ico->height;
|
||||
c->title = malloc(100);
|
||||
if (c->title)
|
||||
snprintf(c->title, 100, messages_get("ICOTitle"), c->width,
|
||||
c->height, c->source_size);
|
||||
c->size += (ico->width * ico->height * 4) + 16 + 44 + 100;
|
||||
|
||||
/* exit as a success */
|
||||
bmp = ico_find(c->data.ico.ico, 255, 255);
|
||||
assert(bmp);
|
||||
c->bitmap = bmp->bitmap;
|
||||
c->status = CONTENT_STATUS_DONE;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nsico_redraw(struct content *c, int x, int y,
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, unsigned long background_colour) {
|
||||
struct bmp_image *bmp = ico_find(c->data.ico.ico, width, height);
|
||||
if (!bmp->decoded)
|
||||
bmp_decode(bmp);
|
||||
c->bitmap = bmp->bitmap;
|
||||
return plot.bitmap(x, y, width, height, c->bitmap,
|
||||
background_colour);
|
||||
}
|
||||
|
||||
|
||||
bool nsico_redraw_tiled(struct content *c, int x, int y,
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, unsigned long background_colour,
|
||||
bool repeat_x, bool repeat_y) {
|
||||
struct bmp_image *bmp = ico_find(c->data.ico.ico, width, height);
|
||||
if (!bmp->decoded)
|
||||
bmp_decode(bmp);
|
||||
c->bitmap = bmp->bitmap;
|
||||
return plot.bitmap_tile(x, y, width, height, c->bitmap,
|
||||
background_colour, repeat_x, repeat_y);
|
||||
}
|
||||
|
||||
|
||||
void nsico_destroy(struct content *c)
|
||||
{
|
||||
ico_finalise(c->data.ico.ico);
|
||||
free(c->data.ico.ico);
|
||||
free(c->title);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* This file is part of NetSurf, http://netsurf.sourceforge.net/
|
||||
* Licensed under the GNU General Public License,
|
||||
* http://www.opensource.org/licenses/gpl-license
|
||||
* Copyright 2006 Richard Wilson <info@tinct.net>
|
||||
*/
|
||||
|
||||
#ifndef _NETSURF_IMAGE_ICO_H_
|
||||
#define _NETSURF_IMAGE_ICO_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "netsurf/image/bmpread.h"
|
||||
|
||||
struct content;
|
||||
|
||||
struct content_ico_data {
|
||||
struct ico_collection *ico; /** ICO collection data */
|
||||
};
|
||||
|
||||
bool nsico_create(struct content *c, const char *params[]);
|
||||
bool nsico_convert(struct content *c, int width, int height);
|
||||
void nsico_destroy(struct content *c);
|
||||
bool nsico_redraw(struct content *c, int x, int y,
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, unsigned long background_colour);
|
||||
bool nsico_redraw_tiled(struct content *c, int x, int y,
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, unsigned long background_colour,
|
||||
bool repeat_x, bool repeat_y);
|
||||
|
||||
#endif
|
|
@ -23,8 +23,10 @@ struct type_entry {
|
|||
char mime_type[40];
|
||||
};
|
||||
static const struct type_entry type_map[] = {
|
||||
{0x132, "image/ico"},
|
||||
{0x188, "application/x-shockwave-flash"},
|
||||
{0x695, "image/gif"},
|
||||
{0x69c, "image/x-ms-bmp"},
|
||||
{0xaff, "image/x-drawfile"},
|
||||
{0xb60, "image/png"},
|
||||
{0xc85, "image/jpeg"},
|
||||
|
@ -247,6 +249,7 @@ int ro_content_filetype_from_type(content_type type) {
|
|||
#endif
|
||||
#ifdef WITH_BMP
|
||||
case CONTENT_BMP: return 0x69c;
|
||||
case CONTENT_ICO: return 0x132;
|
||||
#endif
|
||||
#ifdef WITH_SPRITE
|
||||
case CONTENT_SPRITE: return 0xff9;
|
||||
|
|
|
@ -112,6 +112,9 @@
|
|||
#ifndef FILETYPE_BMP
|
||||
#define FILETYPE_BMP 0x69c
|
||||
#endif
|
||||
#ifndef FILETYPE_ICO
|
||||
#define FILETYPE_ICO 0x132
|
||||
#endif
|
||||
#ifndef FILETYPE_PNG
|
||||
#define FILETYPE_PNG 0xb60
|
||||
#endif
|
||||
|
@ -1496,6 +1499,7 @@ void ro_msg_dataload(wimp_message *message)
|
|||
case FILETYPE_MNG:
|
||||
case FILETYPE_GIF:
|
||||
case FILETYPE_BMP:
|
||||
case FILETYPE_ICO:
|
||||
case osfile_TYPE_DRAW:
|
||||
case FILETYPE_PNG:
|
||||
case FILETYPE_JPEG:
|
||||
|
@ -1784,6 +1788,7 @@ void ro_msg_datasave(wimp_message *message)
|
|||
case FILETYPE_MNG:
|
||||
case FILETYPE_GIF:
|
||||
case FILETYPE_BMP:
|
||||
case FILETYPE_ICO:
|
||||
case osfile_TYPE_DRAW:
|
||||
case FILETYPE_PNG:
|
||||
case FILETYPE_JPEG:
|
||||
|
|
|
@ -815,6 +815,7 @@ void ro_gui_save_object_native(struct content *c, char *path)
|
|||
#endif
|
||||
#ifdef WITH_BMP
|
||||
case CONTENT_BMP:
|
||||
case CONTENT_ICO:
|
||||
bitmap_save(c->bitmap, path);
|
||||
break;
|
||||
#endif
|
||||
|
|
|
@ -498,6 +498,7 @@ void ro_gui_window_redraw(struct gui_window *g, wimp_draw *redraw)
|
|||
#endif
|
||||
#ifdef WITH_BMP
|
||||
case CONTENT_BMP:
|
||||
case CONTENT_ICO:
|
||||
#endif
|
||||
#ifdef WITH_MNG
|
||||
case CONTENT_JNG:
|
||||
|
|
Loading…
Reference in New Issue