[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:
Richard Wilson 2006-02-26 02:25:19 +00:00
parent da4a9313f1
commit 60ea34ad48
16 changed files with 440 additions and 48 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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,

View File

@ -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;

View File

@ -30,6 +30,7 @@ typedef enum {
#endif
#ifdef WITH_BMP
CONTENT_BMP,
CONTENT_ICO,
#endif
#ifdef WITH_MNG
CONTENT_PNG,

View File

@ -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,

View File

@ -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);
}
}

View File

@ -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

118
image/ico.c Normal file
View File

@ -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

33
image/ico.h Normal file
View File

@ -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

View File

@ -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;

View File

@ -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:

View File

@ -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

View File

@ -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: