119
ico_init (const gchar *filename,
122
memset (ico, 0, sizeof (MsIcon));
124
if (! (ico->fp = fopen (filename, "rb")))
126
g_message (_("Could not open '%s' for reading: %s"),
127
gimp_filename_to_utf8 (filename), g_strerror (errno));
131
ico->filename = filename;
133
ico->cp += ico_read_int16 (ico->fp, &ico->reserved, 1);
134
ico->cp += ico_read_int16 (ico->fp, &ico->resource_type, 1);
136
/* Icon files use 1 as resource type, that's what I wrote this for.
137
From descriptions on the web it seems as if this loader should
138
also be able to handle Win 3.11 - Win 95 cursor files (.cur),
139
which use resource type 2. I haven't tested this though. */
140
if (ico->reserved != 0 ||
141
(ico->resource_type != 1 && ico->resource_type != 2))
125
ico_read_init (FILE *fp)
127
IcoFileHeader header;
128
/* read and check file header */
129
if (!ico_read_int16 (fp, &header.reserved, 1)
130
|| !ico_read_int16 (fp, &header.resource_type, 1)
131
|| !ico_read_int16 (fp, &header.icon_count, 1)
132
|| header.reserved != 0
133
|| header.resource_type != 1)
137
return header.icon_count;
142
ico_read_size (FILE *fp,
152
if ( fseek (fp, info->offset, SEEK_SET) < 0 )
155
ico_read_int32 (fp, &magic, 1);
156
if (magic == ICO_PNG_MAGIC)
158
png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL,
162
info_ptr = png_create_info_struct (png_ptr);
165
png_destroy_read_struct (&png_ptr, NULL, NULL);
168
if (setjmp (png_jmpbuf (png_ptr)))
170
png_destroy_read_struct (&png_ptr, NULL, NULL);
173
png_init_io (png_ptr, fp);
174
png_set_sig_bytes (png_ptr, 4);
175
png_read_info (png_ptr, info_ptr);
176
png_get_IHDR (png_ptr, info_ptr, &w, &h, &bpp, &color_type,
178
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
181
D(("ico_read_size: PNG: %ix%i\n", info->width, info->height));
184
else if (magic == 40)
186
if (ico_read_int32 (fp, &info->width, 1)
187
&& ico_read_int32 (fp, &info->height, 1))
190
D(("ico_read_size: ICO: %ix%i\n", info->width, info->height));
204
ico_read_info (FILE *fp,
208
IcoFileEntry *entries;
211
/* read icon entries */
212
entries = g_new (IcoFileEntry, icon_count);
213
if ( fread (entries, sizeof(IcoFileEntry), icon_count, fp) <= 0 )
219
info = g_new (IcoLoadInfo, icon_count);
220
for (i = 0; i < icon_count; i++)
222
info[i].width = entries[i].width;
223
info[i].height = entries[i].height;
224
info[i].bpp = GUINT16_FROM_LE (entries[i].bpp);
225
info[i].size = GUINT32_FROM_LE (entries[i].size);
226
info[i].offset = GUINT32_FROM_LE (entries[i].offset);
228
if (info[i].width == 0 || info[i].height == 0)
230
ico_read_size (fp, info+i);
233
D(("ico_read_info: %ix%i (%i bits, size: %i, offset: %i)\n",
234
info[i].width, info[i].height, info[i].bpp,
235
info[i].size, info[i].offset));
243
ico_read_png (FILE *fp,
259
png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
262
info = png_create_info_struct (png_ptr);
265
png_destroy_read_struct (&png_ptr, NULL, NULL);
269
if (setjmp (png_jmpbuf (png_ptr)))
271
png_destroy_read_struct (&png_ptr, &info, NULL);
275
png_init_io (png_ptr, fp);
276
png_set_sig_bytes (png_ptr, 4);
277
png_read_info (png_ptr, info);
278
png_get_IHDR (png_ptr, info, &w, &h, &bit_depth, &color_type,
282
png_destroy_read_struct (&png_ptr, &info, NULL);
285
D(("ico_read_png: %ix%i, %i bits, %i type\n", (gint)w, (gint)h,
286
bit_depth, color_type));
289
case PNG_COLOR_TYPE_GRAY:
290
png_set_gray_1_2_4_to_8 (png_ptr);
291
if ( bit_depth == 16 )
292
png_set_strip_16 (png_ptr);
293
png_set_gray_to_rgb (png_ptr);
294
png_set_add_alpha (png_ptr, 0xff, PNG_FILLER_AFTER);
296
case PNG_COLOR_TYPE_GRAY_ALPHA:
297
png_set_gray_1_2_4_to_8 (png_ptr);
298
if ( bit_depth == 16 )
299
png_set_strip_16 (png_ptr);
300
png_set_gray_to_rgb (png_ptr);
302
case PNG_COLOR_TYPE_PALETTE:
303
png_set_palette_to_rgb (png_ptr);
304
if (png_get_valid (png_ptr, info, PNG_INFO_tRNS))
305
png_set_tRNS_to_alpha (png_ptr);
307
png_set_add_alpha (png_ptr, 0xff, PNG_FILLER_AFTER);
309
case PNG_COLOR_TYPE_RGB:
311
png_set_strip_16 (png_ptr);
312
png_set_add_alpha (png_ptr, 0xff, PNG_FILLER_AFTER);
314
case PNG_COLOR_TYPE_RGB_ALPHA:
316
png_set_strip_16 (png_ptr);
322
rows = g_new (guint32*, h);
323
rows[0] = (guint32*) buffer;
324
for (i = 1; i < h; i++)
325
rows[i] = rows[i-1] + w;
326
png_read_image (png_ptr, (png_bytepp) rows);
327
png_destroy_read_struct (&png_ptr, &info, NULL);
152
ico_read_entry (MsIcon *ico,
158
ico->cp += ico_read_int8 (ico->fp, &entry->width, 1);
159
ico->cp += ico_read_int8 (ico->fp, &entry->height, 1);
160
ico->cp += ico_read_int8 (ico->fp, &entry->num_colors, 1);
161
ico->cp += ico_read_int8 (ico->fp, &entry->reserved, 1);
163
ico->cp += ico_read_int16 (ico->fp, &entry->num_planes, 1);
164
ico->cp += ico_read_int16 (ico->fp, &entry->bpp, 1);
166
ico->cp += ico_read_int32 (ico->fp, &entry->size, 1);
167
ico->cp += ico_read_int32 (ico->fp, &entry->offset, 1);
169
D(("Read entry with w: "
170
"%i, h: %i, num_colors: %i, bpp: %i, size %i, offset %i\n",
171
entry->width, entry->height, entry->num_colors, entry->bpp,
172
entry->size, entry->offset));
177
ico_read_data (MsIcon *ico,
187
D(("Reading data for icon %i ------------------------------\n", icon_num));
189
entry = &ico->icon_dir[icon_num];
190
data = &ico->icon_data[icon_num];
192
ico->cp = entry->offset;
194
if (fseek (ico->fp, entry->offset, SEEK_SET) < 0)
197
D((" starting at offset %i\n", entry->offset));
199
ico->cp += ico_read_int32 (ico->fp, &data->header_size, 1);
200
ico->cp += ico_read_int32 (ico->fp, &data->width, 1);
201
ico->cp += ico_read_int32 (ico->fp, &data->height, 1);
203
ico->cp += ico_read_int16 (ico->fp, &data->planes, 1);
204
ico->cp += ico_read_int16 (ico->fp, &data->bpp, 1);
206
ico->cp += ico_read_int32 (ico->fp, &data->compression, 1);
207
ico->cp += ico_read_int32 (ico->fp, &data->image_size, 1);
208
ico->cp += ico_read_int32 (ico->fp, &data->x_res, 1);
209
ico->cp += ico_read_int32 (ico->fp, &data->y_res, 1);
210
ico->cp += ico_read_int32 (ico->fp, &data->used_clrs, 1);
211
ico->cp += ico_read_int32 (ico->fp, &data->important_clrs, 1);
213
D((" header size %i, "
214
"w %i, h %i, planes %i, size %i, bpp %i, used %i, imp %i.\n",
215
data->header_size, data->width, data->height,
216
data->planes, data->image_size, data->bpp,
217
data->used_clrs, data->important_clrs));
221
if (data->used_clrs == 0)
222
data->used_clrs = (1 << data->bpp);
224
D((" allocating a %i-slot palette for %i bpp.\n",
225
data->used_clrs, data->bpp));
227
data->palette = g_new0 (guint32, data->used_clrs);
228
ico->cp += ico_read_int8 (ico->fp,
229
(guint8 *) data->palette, data->used_clrs * 4);
232
data->xor_map = ico_alloc_map (entry->width, entry->height,
234
ico->cp += ico_read_int8 (ico->fp, data->xor_map, length);
235
D((" length of xor_map: %i\n", length));
237
/* Read in and_map. It's padded out to 32 bits per line: */
238
data->and_map = ico_alloc_map (entry->width, entry->height, 1, &length);
239
ico->cp += ico_read_int8 (ico->fp, data->and_map, length);
240
D((" length of and_map: %i\n", length));
245
ico_load (MsIcon *ico)
252
ico->cp += ico_read_int16 (ico->fp, &ico->icon_count, 1);
253
ico->icon_dir = g_new0 (MsIconEntry, ico->icon_count);
254
ico->icon_data = g_new0 (MsIconData, ico->icon_count);
256
D(("*** %s: Microsoft icon file, containing %i icon(s)\n",
257
ico->filename, ico->icon_count));
259
for (i = 0; i < ico->icon_count; i++)
260
ico_read_entry(ico, &ico->icon_dir[i]);
262
for (i = 0; i < ico->icon_count; i++)
263
ico_read_data(ico, i);
268
ico_get_bit_from_data (guint8 *data,
333
ico_get_bit_from_data (const guint8 *data,
313
ico_get_byte_from_data (guint8 *data,
378
ico_get_byte_from_data (const guint8 *data,
321
386
/* width per line in multiples of 32 bits */
322
width32 = (line_width % 4 == 0 ? line_width/4 : line_width/4 + 1);
387
width32 = (line_width % 4 == 0 ? line_width / 4 : line_width / 4 + 1);
323
388
line = byte / line_width;
324
389
offset = byte % line_width;
326
391
return data[line * width32 * 4 + offset];
395
ico_read_icon (FILE *fp,
402
IcoFileDataHeader data;
405
guchar *xor_map, *and_map;
413
data.header_size = header_size;
414
ico_read_int32 (fp, &data.width, 1);
415
ico_read_int32 (fp, &data.height, 1);
416
ico_read_int16 (fp, &data.planes, 1);
417
ico_read_int16 (fp, &data.bpp, 1);
418
ico_read_int32 (fp, &data.compression, 1);
419
ico_read_int32 (fp, &data.image_size, 1);
420
ico_read_int32 (fp, &data.x_res, 1);
421
ico_read_int32 (fp, &data.y_res, 1);
422
ico_read_int32 (fp, &data.used_clrs, 1);
423
ico_read_int32 (fp, &data.important_clrs, 1);
425
D((" header size %i, "
426
"w %i, h %i, planes %i, size %i, bpp %i, used %i, imp %i.\n",
427
data.header_size, data.width, data.height,
428
data.planes, data.image_size, data.bpp,
429
data.used_clrs, data.important_clrs));
432
|| data.compression != 0)
434
D(("skipping image: invalid header\n"));
438
if (data.bpp != 1 && data.bpp != 4
439
&& data.bpp != 8 && data.bpp != 24
442
D(("skipping image: invalid depth: %i\n", data.bpp));
446
if (data.width * data.height * 2 > maxsize)
448
D(("skipping image: too large\n"));
457
if (data.used_clrs == 0)
458
data.used_clrs = (1 << data.bpp);
460
D((" allocating a %i-slot palette for %i bpp.\n",
461
data.used_clrs, data.bpp));
463
palette = g_new0 (guint32, data.used_clrs);
464
ico_read_int8 (fp, (guint8 *) palette, data.used_clrs * 4);
467
xor_map = ico_alloc_map (w, h, data.bpp, &length);
468
ico_read_int8 (fp, xor_map, length);
469
D((" length of xor_map: %i\n", length));
471
/* Read in and_map. It's padded out to 32 bits per line: */
472
and_map = ico_alloc_map (w, h, 1, &length);
473
ico_read_int8 (fp, and_map, length);
474
D((" length of and_map: %i\n", length));
476
dest_vec = (guint32 *) buffer;
480
for (y = 0; y < h; y++)
481
for (x = 0; x < w; x++)
483
guint32 color = palette[ico_get_bit_from_data (xor_map,
485
guint32 *dest = dest_vec + (h - 1 - y) * w + x;
487
R_VAL_GIMP (dest) = R_VAL (&color);
488
G_VAL_GIMP (dest) = G_VAL (&color);
489
B_VAL_GIMP (dest) = B_VAL (&color);
491
if (ico_get_bit_from_data (and_map, w, y * w + x))
492
A_VAL_GIMP (dest) = 0;
494
A_VAL_GIMP (dest) = 255;
499
for (y = 0; y < h; y++)
500
for (x = 0; x < w; x++)
502
guint32 color = palette[ico_get_nibble_from_data (xor_map,
504
guint32 *dest = dest_vec + (h - 1 - y) * w + x;
506
R_VAL_GIMP (dest) = R_VAL (&color);
507
G_VAL_GIMP (dest) = G_VAL (&color);
508
B_VAL_GIMP (dest) = B_VAL (&color);
510
if (ico_get_bit_from_data (and_map, w, y * w + x))
511
A_VAL_GIMP (dest) = 0;
513
A_VAL_GIMP (dest) = 255;
518
for (y = 0; y < h; y++)
519
for (x = 0; x < w; x++)
521
guint32 color = palette[ico_get_byte_from_data (xor_map,
523
guint32 *dest = dest_vec + (h - 1 - y) * w + x;
525
R_VAL_GIMP (dest) = R_VAL (&color);
526
G_VAL_GIMP (dest) = G_VAL (&color);
527
B_VAL_GIMP (dest) = B_VAL (&color);
529
if (ico_get_bit_from_data (and_map, w, y * w + x))
530
A_VAL_GIMP (dest) = 0;
532
A_VAL_GIMP (dest) = 255;
538
gint bytespp = data.bpp / 8;
540
rowstride = ico_rowstride (w, data.bpp);
542
for (y = 0; y < h; y++)
544
row = xor_map + rowstride * y;
546
for (x = 0; x < w; x++)
548
guint32 *dest = dest_vec + (h - 1 - y) * w + x;
550
B_VAL_GIMP (dest) = row[0];
551
G_VAL_GIMP (dest) = row[1];
552
R_VAL_GIMP (dest) = row[2];
556
if (ico_get_bit_from_data (and_map, w, y * w + x))
557
A_VAL_GIMP (dest) = 0;
559
A_VAL_GIMP (dest) = 255;
563
A_VAL_GIMP (dest) = row[3];
331
ico_to_gimp (MsIcon *ico)
333
gint icon_nr, x, y, w, h, max_w, max_h;
339
gint32 image, layer, first_layer = -1;
340
const char *layer_name = N_("Icon #%i");
343
GimpDrawable *drawable;
345
/* Do a quick scan of the icons in the file to find the
346
largest icon contained ... */
348
max_w = 0; max_h = 0;
350
for (icon_nr = 0; icon_nr < ico->icon_count; icon_nr++)
352
if (ico->icon_dir[icon_nr].width > max_w)
353
max_w = ico->icon_dir[icon_nr].width;
354
if (ico->icon_dir[icon_nr].height > max_h)
355
max_h = ico->icon_dir[icon_nr].height;
358
/* Allocate the Gimp image */
360
image = gimp_image_new (max_w, max_h, GIMP_RGB);
361
gimp_image_set_filename (image, ico->filename);
363
/* Scan icons again and set up a layer for each icon */
365
for (icon_nr = 0; icon_nr < ico->icon_count; icon_nr++)
367
GimpPixelRgn pixel_rgn;
369
gimp_progress_update ((gdouble) icon_nr / (gdouble) ico->icon_count);
371
w = ico->icon_dir[icon_nr].width;
372
h = ico->icon_dir[icon_nr].height;
373
palette = ico->icon_data[icon_nr].palette;
374
xor_map = ico->icon_data[icon_nr].xor_map;
375
and_map = ico->icon_data[icon_nr].and_map;
376
idata = &ico->icon_data[icon_nr];
377
ientry = &ico->icon_dir[icon_nr];
379
g_snprintf (s, MAXLEN, gettext (layer_name), icon_nr + 1);
381
layer = gimp_layer_new (image, s, w, h,
382
GIMP_RGBA_IMAGE, 100, GIMP_NORMAL_MODE);
384
if (first_layer == -1)
387
gimp_image_add_layer (image, layer, icon_nr);
388
drawable = gimp_drawable_get (layer);
390
dest_vec = g_malloc (w * h * 4);
395
for (y = 0; y < h; y++)
396
for (x = 0; x < w; x++)
398
guint32 color = palette[ico_get_bit_from_data (xor_map,
400
guint32 *dest = &(dest_vec[(h-1-y) * w + x]);
402
R_VAL_GIMP (dest) = R_VAL (&color);
403
G_VAL_GIMP (dest) = G_VAL (&color);
404
B_VAL_GIMP (dest) = B_VAL (&color);
406
if (ico_get_bit_from_data (and_map, w, y*w + x))
407
A_VAL_GIMP (dest) = 0;
409
A_VAL_GIMP (dest) = 255;
414
for (y = 0; y < h; y++)
415
for (x = 0; x < w; x++)
417
guint32 color = palette[ico_get_nibble_from_data (xor_map,
419
guint32 *dest = &(dest_vec[(h-1-y) * w + x]);
421
R_VAL_GIMP (dest) = R_VAL (&color);
422
G_VAL_GIMP (dest) = G_VAL (&color);
423
B_VAL_GIMP (dest) = B_VAL (&color);
425
if (ico_get_bit_from_data (and_map, w, y*w + x))
426
A_VAL_GIMP (dest) = 0;
428
A_VAL_GIMP (dest) = 255;
433
for (y = 0; y < h; y++)
434
for (x = 0; x < w; x++)
436
guint32 color = palette[ico_get_byte_from_data (xor_map,
438
guint32 *dest = &(dest_vec[(h-1-y) * w + x]);
440
R_VAL_GIMP (dest) = R_VAL (&color);
441
G_VAL_GIMP (dest) = G_VAL (&color);
442
B_VAL_GIMP (dest) = B_VAL (&color);
444
if (ico_get_bit_from_data (and_map, w, y*w + x))
445
A_VAL_GIMP (dest) = 0;
447
A_VAL_GIMP (dest) = 255;
453
int bytespp = idata->bpp/8;
455
for (y = 0; y < h; y++)
456
for (x = 0; x < w; x++)
458
guint32 *dest = &(dest_vec[(h-1-y) * w + x]);
460
B_VAL_GIMP(dest) = xor_map[(y * w + x) * bytespp];
461
G_VAL_GIMP(dest) = xor_map[(y * w + x) * bytespp + 1];
462
R_VAL_GIMP(dest) = xor_map[(y * w + x) * bytespp + 2];
466
if (ico_get_bit_from_data (and_map, w, y*w + x))
467
A_VAL_GIMP (dest) = 0;
469
A_VAL_GIMP (dest) = 255;
473
A_VAL_GIMP (dest) = xor_map[(y * w + x) * bytespp + 3];
479
gimp_pixel_rgn_init (&pixel_rgn, drawable,
480
0, 0, drawable->width, drawable->height,
482
gimp_pixel_rgn_set_rect (&pixel_rgn, (guchar*) dest_vec,
483
0, 0, drawable->width, drawable->height);
487
gimp_drawable_detach (drawable);
490
gimp_image_set_active_layer (image, first_layer);
492
gimp_progress_update (1.0);
499
LoadICO (const gchar *filename)
505
temp = g_strdup_printf (_("Opening '%s'..."),
506
gimp_filename_to_utf8 (filename));
507
gimp_progress_init (temp);
510
if (! ico_init (filename, &ico))
515
if ( (image_ID = ico_to_gimp (&ico)) < 0)
523
D(("*** icon successfully loaded.\n\n"));
581
ico_load_layer (FILE *fp,
591
GimpDrawable *drawable;
592
GimpPixelRgn pixel_rgn;
593
gchar buf [ICO_MAXBUF];
595
if ( fseek (fp, info->offset, SEEK_SET) < 0
596
|| !ico_read_int32 (fp, &first_bytes, 1) )
599
if (first_bytes == ICO_PNG_MAGIC)
601
if (!ico_read_png (fp, first_bytes, buffer, maxsize, &width, &height))
604
else if (first_bytes == 40)
606
if (!ico_read_icon (fp, first_bytes, buffer, maxsize, &width, &height))
615
/* read successfully. add to image */
616
g_snprintf (buf, sizeof (buf), _("Icon #%i"), icon_num+1);
617
layer = gimp_layer_new (image, buf, width, height,
618
GIMP_RGBA_IMAGE, 100, GIMP_NORMAL_MODE);
619
gimp_image_add_layer (image, layer, icon_num);
620
drawable = gimp_drawable_get (layer);
621
gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0,
622
drawable->width, drawable->height, TRUE, FALSE);
623
gimp_pixel_rgn_set_rect (&pixel_rgn, (const guchar*) buffer,
624
0, 0, drawable->width,
626
gimp_drawable_detach (drawable);
633
ico_load_image (const gchar *filename)
637
gint max_width, max_height;
645
gimp_progress_init_printf (_("Opening '%s'"),
646
gimp_filename_to_utf8 (filename));
648
fp = g_fopen (filename, "rb");
651
g_message (_("Could not open '%s' for reading: %s"),
652
gimp_filename_to_utf8 (filename), g_strerror (errno));
656
icon_count = ico_read_init (fp);
663
info = ico_read_info (fp, icon_count);
670
/* find width and height of image */
673
for (i = 0; i < icon_count; i++)
675
if ( info[i].width > max_width )
676
max_width = info[i].width;
677
if ( info[i].height > max_height )
678
max_height = info[i].height;
680
if ( max_width <= 0 || max_height <= 0 )
686
D(("image size: %ix%i\n", max_width, max_height));
688
image = gimp_image_new (max_width, max_height, GIMP_RGB);
689
gimp_image_set_filename (image, filename);
691
maxsize = max_width * max_height * 4;
692
buffer = g_new (guchar, max_width * max_height * 4);
693
for (i = 0; i < icon_count; i++)
695
layer = ico_load_layer (fp, image, i, buffer, maxsize, info+i);
701
gimp_progress_update (1.0);
707
ico_load_thumbnail_image (const gchar *filename,
722
gimp_progress_init_printf (_("Opening thumbnail for '%s'"),
723
gimp_filename_to_utf8 (filename));
725
fp = g_fopen (filename, "rb");
728
g_message (_("Could not open '%s' for reading: %s"),
729
gimp_filename_to_utf8 (filename), g_strerror (errno));
733
icon_count = ico_read_init (fp);
740
D(("*** %s: Microsoft icon file, containing %i icon(s)\n",
741
filename, icon_count));
743
info = ico_read_info (fp, icon_count);
750
/* Do a quick scan of the icons in the file to find the best match */
751
for (i = 0; i < icon_count; i++)
753
if ((info[i].width > w && w < *width) ||
754
(info[i].height > h && h < *height))
762
else if ( w == info[i].width
763
&& h == info[i].height
764
&& info[i].bpp > bpp )
772
if (w <= 0 || h <= 0)
775
image = gimp_image_new (w, h, GIMP_RGB);
776
buffer = g_new (guchar, w*h*4);
777
layer = ico_load_layer (fp, image, match, buffer, w*h*4, info+match);
783
D(("*** thumbnail successfully loaded.\n\n"));
785
gimp_progress_update (1.0);