зеркало из https://github.com/mozilla/pjs.git
768 строки
19 KiB
C
768 строки
19 KiB
C
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|||
|
*
|
|||
|
* The contents of this file are subject to the Netscape Public License
|
|||
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|||
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|||
|
* http://www.mozilla.org/NPL/
|
|||
|
*
|
|||
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|||
|
* for the specific language governing rights and limitations under the
|
|||
|
* NPL.
|
|||
|
*
|
|||
|
* The Initial Developer of this code under the NPL is Netscape
|
|||
|
* Communications Corporation. Portions created by Netscape are
|
|||
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|||
|
* Reserved.
|
|||
|
*/
|
|||
|
/**********************************************************************
|
|||
|
mkanim.c
|
|||
|
By Daniel Malmer
|
|||
|
|
|||
|
This code was mostly taken from mkicons.c.
|
|||
|
|
|||
|
Given a list of filenames, creates a datafile that is read in by the
|
|||
|
browser at run-time. The images in the datafile will be used as the
|
|||
|
custom animation.
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
mkanim large-file1 large-file2... large-filen small-file1 small-file2...
|
|||
|
small-filen
|
|||
|
|
|||
|
**********************************************************************/
|
|||
|
|
|||
|
/*
|
|||
|
mkicons.c --- converting transparent GIFs to embeddable XImage data.
|
|||
|
Created: Jamie Zawinski <jwz@netscape.com>, 17-Aug-95.
|
|||
|
(Danger. Here be monsters.)
|
|||
|
*/
|
|||
|
|
|||
|
#define MAX_ANIM_FRAMES 50
|
|||
|
|
|||
|
#ifdef sgi
|
|||
|
#include <bstring.h>
|
|||
|
#else
|
|||
|
#include <string.h>
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef _HPUX_SOURCE
|
|||
|
typedef unsigned char uchar_t;
|
|||
|
#endif
|
|||
|
|
|||
|
#include "if.h"
|
|||
|
#include "prtypes.h"
|
|||
|
#include <plevent.h>
|
|||
|
#include <prtypes.h>
|
|||
|
#include "libevent.h"
|
|||
|
|
|||
|
extern void append_to_output_file(char* data, int len);
|
|||
|
|
|||
|
/* =========================================================================
|
|||
|
All this junk is just to get it to link.
|
|||
|
=========================================================================
|
|||
|
*/
|
|||
|
|
|||
|
void * FE_SetTimeout(TimeoutCallbackFunction func, void * closure,
|
|||
|
uint32 msecs) { return 0; }
|
|||
|
void FE_ClearTimeout(void *timer_id) {}
|
|||
|
void XP_Trace(const char * format, ...) {}
|
|||
|
void FE_ImageDelete(IL_Image *portableImage) {}
|
|||
|
int32 NET_GetMemoryCacheSize(void) { return 1000000; }
|
|||
|
int32 NET_GetMaxMemoryCacheSize(void) { return 1000000; }
|
|||
|
void NET_FreeURLStruct(URL_Struct * URL_s) {}
|
|||
|
int NET_InterruptWindow(MWContext * window_id) {return 0;}
|
|||
|
URL_Struct *NET_CreateURLStruct(const char *url, NET_ReloadMethod reload) { return 0; }
|
|||
|
History_entry * SHIST_GetCurrent(History * hist) { return 0; }
|
|||
|
int NET_GetURL (URL_Struct * URL_s, FO_Present_Types output_format,
|
|||
|
MWContext * context, Net_GetUrlExitFunc* exit_routine)
|
|||
|
{ return -1; }
|
|||
|
Bool LO_BlockedOnImage(MWContext *c, LO_ImageStruct *image) { return FALSE; }
|
|||
|
Bool NET_IsURLInDiskCache(URL_Struct *URL_s) {return TRUE;}
|
|||
|
XP_Bool NET_IsLocalFileURL(char *address) {return TRUE;}
|
|||
|
|
|||
|
NET_StreamClass * NET_StreamBuilder (FO_Present_Types format_out,
|
|||
|
URL_Struct *anchor, MWContext *window_id)
|
|||
|
{ return 0; }
|
|||
|
|
|||
|
Bool NET_AreThereActiveConnectionsForWindow(MWContext * window_id)
|
|||
|
{ return FALSE; }
|
|||
|
Bool NET_AreThereStoppableConnectionsForWindow(MWContext * window_id)
|
|||
|
{ return FALSE; }
|
|||
|
void LO_RefreshAnchors(MWContext *context) { }
|
|||
|
void GH_UpdateGlobalHistory(URL_Struct * URL_s) { }
|
|||
|
char * NET_EscapeHTML(const char * string) { return (char *)string; }
|
|||
|
Bool LO_LocateNamedAnchor(MWContext *context, URL_Struct *url_struct,
|
|||
|
int32 *xpos, int32 *ypos) { return FALSE; }
|
|||
|
Bool LO_HasBGImage(MWContext *context) {return FALSE; }
|
|||
|
|
|||
|
void FE_UpdateStopState(MWContext *context) {}
|
|||
|
|
|||
|
void
|
|||
|
FE_Alert (MWContext *context, const char *message) {}
|
|||
|
|
|||
|
void ET_RemoveWindowContext(MWContext *context, ETVoidPtrFunc fn,
|
|||
|
void *data) { }
|
|||
|
|
|||
|
extern int il_first_write(NET_StreamClass *stream, const unsigned char *str, int32 len);
|
|||
|
|
|||
|
void fe_ReLayout (MWContext *context, NET_ReloadMethod force_reload) {}
|
|||
|
|
|||
|
char *XP_GetBuiltinString(int16 i);
|
|||
|
|
|||
|
char *
|
|||
|
XP_GetString(int16 i)
|
|||
|
{
|
|||
|
return XP_GetBuiltinString(i);
|
|||
|
}
|
|||
|
|
|||
|
Bool
|
|||
|
NET_IsURLInMemCache(URL_Struct *URL_s)
|
|||
|
{
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/* =========================================================================
|
|||
|
Now it gets REALLY nasty.
|
|||
|
=========================================================================
|
|||
|
*/
|
|||
|
|
|||
|
struct image {
|
|||
|
int width, height;
|
|||
|
char *color_bits;
|
|||
|
char *mono_bits;
|
|||
|
char *mask_bits;
|
|||
|
};
|
|||
|
|
|||
|
int total_images = 0;
|
|||
|
struct image images[500] = { { 0, }, };
|
|||
|
|
|||
|
int total_colors;
|
|||
|
IL_IRGB cmap[256];
|
|||
|
|
|||
|
char* current_file = NULL;
|
|||
|
|
|||
|
int num_frames_small = 0;
|
|||
|
int width_small = 0;
|
|||
|
int height_small = 0;
|
|||
|
|
|||
|
int num_frames_large = 0;
|
|||
|
int width_large = 0;
|
|||
|
int height_large = 0;
|
|||
|
|
|||
|
int in_anim = 0;
|
|||
|
int inactive_icon_p = 0;
|
|||
|
int anim_frames[100] = { 0, };
|
|||
|
|
|||
|
XP_Bool sgi_p = FALSE;
|
|||
|
|
|||
|
static unsigned char *bitrev = 0;
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
* warn
|
|||
|
*/
|
|||
|
void
|
|||
|
warn(char* msg)
|
|||
|
{
|
|||
|
fprintf(stderr, "Warning: %s: %s\n", current_file, msg);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
* error
|
|||
|
*/
|
|||
|
void
|
|||
|
error(char* msg)
|
|||
|
{
|
|||
|
fprintf(stderr, "Error: %s: %s\n", current_file, msg);
|
|||
|
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
* init_reverse_bits
|
|||
|
*/
|
|||
|
static void
|
|||
|
init_reverse_bits(void)
|
|||
|
{
|
|||
|
if(!bitrev)
|
|||
|
{
|
|||
|
int i, x, br;
|
|||
|
bitrev = (unsigned char *)XP_ALLOC(256);
|
|||
|
for(i=0; i<256; i++)
|
|||
|
{
|
|||
|
br = 0;
|
|||
|
for(x=0; x<8; x++)
|
|||
|
{
|
|||
|
br = br<<1;
|
|||
|
if(i&(1<<x))
|
|||
|
br |= 1;
|
|||
|
}
|
|||
|
bitrev[i] = br;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
typedef enum {INITIAL_STATE, LARGE_STATE, SMALL_STATE, ERROR_STATE} image_state;
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
* image_size
|
|||
|
* This routine is registered with the image library to be invoked
|
|||
|
* when it has determined the size of the image that it is processing.
|
|||
|
* Sets the size of the image, and allocates the appropriate memory.
|
|||
|
*/
|
|||
|
int
|
|||
|
image_size (MWContext *context, IL_ImageStatus message,
|
|||
|
IL_Image *il_image, void *data)
|
|||
|
{
|
|||
|
static image_state state = INITIAL_STATE;
|
|||
|
|
|||
|
switch ( state ) {
|
|||
|
case INITIAL_STATE:
|
|||
|
printf("First large frame is %s.\n", current_file);
|
|||
|
printf("Size is %d by %d pixels.\n", il_image->width, il_image->height);
|
|||
|
num_frames_large++;
|
|||
|
width_large = il_image->width;
|
|||
|
height_large = il_image->height;
|
|||
|
state = LARGE_STATE;
|
|||
|
break;
|
|||
|
case LARGE_STATE:
|
|||
|
if ( il_image->width == width_large &&
|
|||
|
il_image->height == height_large ) {
|
|||
|
if ( num_frames_large < MAX_ANIM_FRAMES ) {
|
|||
|
num_frames_large++;
|
|||
|
printf("Reading large frame %d...\n", num_frames_large);
|
|||
|
} else {
|
|||
|
warn("Ignoring. Too many frames for animation.");
|
|||
|
}
|
|||
|
} else {
|
|||
|
printf("First small frame is %s.\n", current_file);
|
|||
|
printf("Size is %d by %d pixels.\n", il_image->width, il_image->height);
|
|||
|
num_frames_small++;
|
|||
|
width_small = il_image->width;
|
|||
|
height_small = il_image->height;
|
|||
|
state = SMALL_STATE;
|
|||
|
}
|
|||
|
break;
|
|||
|
case SMALL_STATE:
|
|||
|
if ( il_image->width == width_small &&
|
|||
|
il_image->height == height_small ) {
|
|||
|
if ( num_frames_small < MAX_ANIM_FRAMES ) {
|
|||
|
num_frames_small++;
|
|||
|
printf("Reading small frame %d...\n", num_frames_small);
|
|||
|
} else {
|
|||
|
warn("Ignoring. Too many frames for animation.");
|
|||
|
}
|
|||
|
} else {
|
|||
|
error("Bad size. Animation frames must have the same size.\n");
|
|||
|
state = ERROR_STATE;
|
|||
|
}
|
|||
|
break;
|
|||
|
case ERROR_STATE:
|
|||
|
break;
|
|||
|
default:
|
|||
|
error("Unexpected error. Reached bad switch.\n");
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if (il_image->bits)
|
|||
|
free (il_image->bits);
|
|||
|
|
|||
|
il_image->bits = malloc (il_image->widthBytes * il_image->height);
|
|||
|
memset (il_image->bits, ~0, (il_image->widthBytes * il_image->height));
|
|||
|
if (!il_image->mask && il_image->transparent)
|
|||
|
{
|
|||
|
int size = il_image->maskWidthBytes * il_image->height;
|
|||
|
il_image->mask = malloc (size);
|
|||
|
memset (il_image->mask, ~0, size);
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
* print_image
|
|||
|
*/
|
|||
|
void
|
|||
|
print_image(IL_Image* il_image)
|
|||
|
{
|
|||
|
printf("---------------------------------------------\n");
|
|||
|
printf("il_image->width = %d\n", il_image->width);
|
|||
|
printf("il_image->height = %d\n", il_image->height);
|
|||
|
printf("il_image->widthBytes = %d\n", il_image->widthBytes);
|
|||
|
printf("il_image->maskWidthBytes = %d\n", il_image->maskWidthBytes);
|
|||
|
printf("il_image->depth = %d\n", il_image->depth);
|
|||
|
printf("il_image->bytesPerPixel = %d\n", il_image->bytesPerPixel);
|
|||
|
printf("il_image->colors = %d\n", il_image->colors);
|
|||
|
printf("il_image->unique_colors = %d\n", il_image->unique_colors);
|
|||
|
printf("il_image->validHeight = %d\n", il_image->validHeight);
|
|||
|
printf("il_image->lastValidHeight = %d\n", il_image->lastValidHeight);
|
|||
|
printf("il_image->has_mask = %s\n", il_image->has_mask ?
|
|||
|
"True" : "False");
|
|||
|
printf("il_image->hasUniqueColormap = %s\n", il_image->hasUniqueColormap ?
|
|||
|
"True" : "False");
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
* get_color
|
|||
|
*/
|
|||
|
int
|
|||
|
get_color(uchar_t r, uchar_t g, uchar_t b)
|
|||
|
{
|
|||
|
int i;
|
|||
|
|
|||
|
#ifdef DEBUG_username
|
|||
|
printf("Trying to find %d %d %d... ", r, g, b);
|
|||
|
#endif
|
|||
|
|
|||
|
for ( i = 0; i < total_colors; i++ ) {
|
|||
|
if ( cmap[i].red == r &&
|
|||
|
cmap[i].green == g &&
|
|||
|
cmap[i].blue == b ) {
|
|||
|
return i;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ( total_colors > 64 ) {
|
|||
|
error("Animations can contain no more than 64 colors.\n");
|
|||
|
}
|
|||
|
|
|||
|
cmap[total_colors].red = r;
|
|||
|
cmap[total_colors].green = g;
|
|||
|
cmap[total_colors].blue = b;
|
|||
|
|
|||
|
total_colors++;
|
|||
|
|
|||
|
return (total_colors-1);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
* image_data
|
|||
|
* This routine is registered with the image library. It is invoked
|
|||
|
* when the image library has image data to be processed. The mono
|
|||
|
* bits, mask bits and color bits are written to the output buffer.
|
|||
|
*/
|
|||
|
void
|
|||
|
image_data (MWContext *context, IL_ImageStatus message, IL_Image *il_image,
|
|||
|
void *data)
|
|||
|
{
|
|||
|
int row_parity;
|
|||
|
unsigned char *s, *m, *scanline, *mask_scanline, *end;
|
|||
|
|
|||
|
#ifdef DEBUG_username
|
|||
|
print_image(il_image);
|
|||
|
#endif
|
|||
|
|
|||
|
if (message != ilComplete) abort ();
|
|||
|
images[total_images].width = il_image->width;
|
|||
|
images[total_images].height = il_image->height;
|
|||
|
if (il_image->depth == 1)
|
|||
|
images[total_images].mono_bits = il_image->bits;
|
|||
|
else
|
|||
|
images[total_images].color_bits = il_image->bits;
|
|||
|
if (il_image->mask)
|
|||
|
images[total_images].mask_bits = il_image->mask;
|
|||
|
|
|||
|
if (il_image->depth == 1)
|
|||
|
return;
|
|||
|
if (il_image->depth != 32) {
|
|||
|
error("Color image depth not 32.\n");
|
|||
|
}
|
|||
|
|
|||
|
/* Generate monochrome icon from color data. */
|
|||
|
scanline = il_image->bits;
|
|||
|
mask_scanline = il_image->mask;
|
|||
|
end = scanline + (il_image->widthBytes * il_image->height);
|
|||
|
row_parity = 0;
|
|||
|
|
|||
|
while (scanline < end)
|
|||
|
{
|
|||
|
unsigned char *scanline_end = scanline + (il_image->width * 4);
|
|||
|
int luminance, pixel;
|
|||
|
int bit = 0;
|
|||
|
uchar_t byte = 0;
|
|||
|
|
|||
|
row_parity ^= 1;
|
|||
|
for (m = mask_scanline, s = scanline; s < scanline_end; s += 4)
|
|||
|
{
|
|||
|
unsigned char r = s[3];
|
|||
|
unsigned char g = s[2];
|
|||
|
unsigned char b = s[1];
|
|||
|
|
|||
|
luminance = (0.299 * r) + (0.587 * g) + (0.114 * b);
|
|||
|
|
|||
|
pixel =
|
|||
|
((luminance < 128)) ||
|
|||
|
((r == 66) && (g == 154) && (b == 167)); /* Magic: blue */
|
|||
|
byte |= pixel << bit++;
|
|||
|
|
|||
|
if ((bit == 8) || ((s + 4) >= scanline_end)) {
|
|||
|
/* Handle transparent areas of the icon */
|
|||
|
if (il_image->mask)
|
|||
|
byte &= bitrev[*m++];
|
|||
|
|
|||
|
append_to_output_file((char*) &byte, 1);
|
|||
|
|
|||
|
bit = 0;
|
|||
|
byte = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
scanline += il_image->widthBytes;
|
|||
|
mask_scanline += il_image->maskWidthBytes;
|
|||
|
}
|
|||
|
|
|||
|
/* Mask data */
|
|||
|
if (il_image->mask)
|
|||
|
{
|
|||
|
scanline = il_image->mask;
|
|||
|
end = scanline + (il_image->maskWidthBytes * il_image->height);
|
|||
|
for (;scanline < end; scanline += il_image->maskWidthBytes)
|
|||
|
{
|
|||
|
unsigned char *scanline_end = scanline + ((il_image->width + 7) / 8);
|
|||
|
for (s = scanline; s < scanline_end; s++)
|
|||
|
{
|
|||
|
append_to_output_file((char*) &(bitrev[*s]), 1);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
append_to_output_file(0, (il_image->width+7)/8*(il_image->height));
|
|||
|
}
|
|||
|
|
|||
|
/* Color icon */
|
|||
|
|
|||
|
scanline = il_image->bits;
|
|||
|
end = scanline + (il_image->widthBytes * il_image->height);
|
|||
|
for (;scanline < end; scanline += il_image->widthBytes)
|
|||
|
{
|
|||
|
unsigned char *scanline_end = scanline + (il_image->width * 4);
|
|||
|
for (s = scanline; s < scanline_end; s += 4)
|
|||
|
{
|
|||
|
unsigned char r = s[3];
|
|||
|
unsigned char g = s[2];
|
|||
|
unsigned char b = s[1];
|
|||
|
int j;
|
|||
|
uchar_t byte;
|
|||
|
j = get_color(r, g, b);
|
|||
|
byte = (uchar_t) j;
|
|||
|
append_to_output_file((char*) &byte, 1);
|
|||
|
|
|||
|
#ifdef DEBUG_username
|
|||
|
for (j = 0; j < total_colors; j++)
|
|||
|
if (r == cmap[j].red &&
|
|||
|
g == cmap[j].green &&
|
|||
|
b == cmap[j].blue)
|
|||
|
{
|
|||
|
byte = (uchar_t) j;
|
|||
|
append_to_output_file((char*) &byte, 1);
|
|||
|
goto DONE;
|
|||
|
}
|
|||
|
error("Error allocated colors.\n");
|
|||
|
DONE:
|
|||
|
;
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (il_image->bits) free (il_image->bits);
|
|||
|
il_image->bits = 0;
|
|||
|
if (il_image->mask) free (il_image->mask);
|
|||
|
il_image->mask = 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
* set_title
|
|||
|
* A no-op.
|
|||
|
*/
|
|||
|
void
|
|||
|
set_title (MWContext *context, char *title)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
* do_file
|
|||
|
* Process an image file.
|
|||
|
*/
|
|||
|
void
|
|||
|
do_file (char *file)
|
|||
|
{
|
|||
|
static int counter = 0;
|
|||
|
FILE *fp;
|
|||
|
char *data;
|
|||
|
int size;
|
|||
|
NET_StreamClass *stream;
|
|||
|
struct stat st;
|
|||
|
char *s;
|
|||
|
|
|||
|
URL_Struct *url;
|
|||
|
il_container *ic;
|
|||
|
il_process *proc;
|
|||
|
MWContext cx;
|
|||
|
ContextFuncs fns;
|
|||
|
IL_IRGB trans;
|
|||
|
|
|||
|
memset (&cx, 0, sizeof(cx));
|
|||
|
memset (&fns, 0, sizeof(fns));
|
|||
|
|
|||
|
url = XP_NEW_ZAP (URL_Struct);
|
|||
|
proc = XP_NEW_ZAP (il_process);
|
|||
|
|
|||
|
url->address = strdup("\000\000");
|
|||
|
cx.funcs = &fns;
|
|||
|
|
|||
|
fns.ImageSize = image_size;
|
|||
|
fns.ImageData = image_data;
|
|||
|
fns.SetDocTitle = set_title;
|
|||
|
|
|||
|
{
|
|||
|
/* make a container */
|
|||
|
ic = XP_NEW_ZAP(il_container);
|
|||
|
ic->hash = 0;
|
|||
|
ic->urlhash = 0;
|
|||
|
ic->cx = &cx;
|
|||
|
ic->forced = 0;
|
|||
|
|
|||
|
ic->image = XP_NEW_ZAP(IL_Image);
|
|||
|
|
|||
|
ic->next = 0;
|
|||
|
ic->ip = proc;
|
|||
|
cx.imageProcess = proc;
|
|||
|
|
|||
|
ic->state = IC_START;
|
|||
|
}
|
|||
|
|
|||
|
url->fe_data = ic;
|
|||
|
|
|||
|
ic->clients = XP_NEW_ZAP(il_client);
|
|||
|
ic->clients->cx = &cx;
|
|||
|
|
|||
|
if ( stat (file, &st) ) {
|
|||
|
perror(file);
|
|||
|
exit(errno);
|
|||
|
}
|
|||
|
|
|||
|
if ( !S_ISREG(st.st_mode) ) {
|
|||
|
fprintf(stderr, "%s: Not a plain file.\n", file);
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
|
|||
|
size = st.st_size;
|
|||
|
|
|||
|
data = (char *) malloc (size + 1);
|
|||
|
fp = fopen (file, "r");
|
|||
|
fread (data, 1, size, fp);
|
|||
|
fclose (fp);
|
|||
|
|
|||
|
current_file = strdup(file);
|
|||
|
|
|||
|
s = strrchr (file, '.');
|
|||
|
if (s) *s = 0;
|
|||
|
s = strrchr (file, '/');
|
|||
|
if (s)
|
|||
|
s++;
|
|||
|
else
|
|||
|
s = file;
|
|||
|
|
|||
|
if (in_anim && strncmp (s, "Anim", 4))
|
|||
|
/* once you've started anim frames, don't stop. */
|
|||
|
abort ();
|
|||
|
|
|||
|
if ((!strcmp (s, "AnimSm00") || !strcmp (s, "AnimHuge00")) ||
|
|||
|
((!strcmp (s, "AnimSm01") || !strcmp (s, "AnimHuge01")) &&
|
|||
|
(!in_anim ||
|
|||
|
anim_frames[in_anim-1] > 1)))
|
|||
|
{
|
|||
|
char *s2;
|
|||
|
|
|||
|
s2 = s - 2;
|
|||
|
while (s2 > file && *s2 != '/')
|
|||
|
s2--;
|
|||
|
s[-1] = 0;
|
|||
|
if (*s2 == '/')
|
|||
|
s2++;
|
|||
|
|
|||
|
in_anim++;
|
|||
|
}
|
|||
|
|
|||
|
if (in_anim)
|
|||
|
{
|
|||
|
if (strncmp (s, "Anim", 4)) abort ();
|
|||
|
anim_frames[in_anim-1]++;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
char *s2 = s;
|
|||
|
while (*s2)
|
|||
|
{
|
|||
|
if (*s2 == '.') *s2 = '_';
|
|||
|
s2++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
trans.red = trans.green = trans.blue = 0xC0;
|
|||
|
|
|||
|
cx.colorSpace = NULL;
|
|||
|
|
|||
|
IL_EnableTrueColor (&cx, 32,
|
|||
|
#if defined(IS_LITTLE_ENDIAN)
|
|||
|
24, 16, 8,
|
|||
|
#elif defined(IS_BIG_ENDIAN)
|
|||
|
0, 8, 16,
|
|||
|
#else
|
|||
|
ERROR! Endianness unknown.
|
|||
|
#endif
|
|||
|
8, 8, 8,
|
|||
|
&trans, FALSE);
|
|||
|
|
|||
|
ic->cs = cx.colorSpace;
|
|||
|
/*IL_SetPreferences (&cx, FALSE, ilClosestColor);*/
|
|||
|
IL_SetPreferences (&cx, FALSE, ilDither);/* XXXM12N Replace with
|
|||
|
IL_SetDisplayMode. */
|
|||
|
url->address[0] = counter++;
|
|||
|
stream = IL_NewStream (FO_PRESENT,
|
|||
|
(strstr (current_file, ".gif") ? (void *) IL_GIF :
|
|||
|
strstr (current_file, ".jpg") ? (void *) IL_JPEG :
|
|||
|
strstr (current_file, ".jpeg") ? (void *) IL_JPEG :
|
|||
|
strstr (current_file, ".xbm") ? (void *) IL_XBM :
|
|||
|
(void *) IL_GIF),
|
|||
|
url, &cx);
|
|||
|
if ( stream->put_block (stream, data, size) < 0 ) {
|
|||
|
error("Couldn't decode file.\n");
|
|||
|
}
|
|||
|
|
|||
|
stream->complete (stream);
|
|||
|
|
|||
|
free(current_file);
|
|||
|
free (data);
|
|||
|
|
|||
|
total_images++;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
uchar_t* output_buf = NULL;
|
|||
|
int output_max_len = 0;
|
|||
|
int output_len = 0;
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
* CHUNKSIZE should be 1024 or something, but make
|
|||
|
* it small to make sure it works.
|
|||
|
*/
|
|||
|
#define CHUNKSIZE 64
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
* append_to_output_file
|
|||
|
* Append the given data to the output buffer. If the resulting data
|
|||
|
* is too large for the currently allocated output buffer, first allocate
|
|||
|
* additional space.
|
|||
|
*/
|
|||
|
void
|
|||
|
append_to_output_file(char* data, int len)
|
|||
|
{
|
|||
|
while ( output_buf == NULL || output_len + len >= output_max_len ) {
|
|||
|
output_max_len+= CHUNKSIZE;
|
|||
|
output_buf = (char*) realloc(output_buf, output_max_len);
|
|||
|
}
|
|||
|
|
|||
|
if ( data ) {
|
|||
|
memcpy(output_buf+output_len, data, len);
|
|||
|
} else {
|
|||
|
memset(output_buf+output_len, 0xff, len);
|
|||
|
}
|
|||
|
|
|||
|
output_len+= len;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#define ANIMATION_FILENAME "animation.dat"
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
* usage
|
|||
|
*/
|
|||
|
void
|
|||
|
usage(char* progname)
|
|||
|
{
|
|||
|
fprintf(stderr, "Usage: %s large-animation-files small-animation-files\n",
|
|||
|
progname);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
* main
|
|||
|
* Process each file given on the command line.
|
|||
|
*/
|
|||
|
int
|
|||
|
main (int argc, char* argv[])
|
|||
|
{
|
|||
|
int i;
|
|||
|
FILE* anim_file;
|
|||
|
|
|||
|
init_reverse_bits();
|
|||
|
|
|||
|
if ( argc < 2 ) {
|
|||
|
usage(argv[0]);
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
|
|||
|
for (i = 1; i < argc; i++) {
|
|||
|
char *filename = argv[i];
|
|||
|
inactive_icon_p = (strstr(filename, ".i.gif") != NULL);
|
|||
|
do_file (filename);
|
|||
|
}
|
|||
|
|
|||
|
if ( (anim_file = fopen(ANIMATION_FILENAME, "w")) == NULL ) {
|
|||
|
perror(ANIMATION_FILENAME);
|
|||
|
exit(errno);
|
|||
|
}
|
|||
|
|
|||
|
fprintf(anim_file, "%d %d %d\n", num_frames_large, width_large, height_large);
|
|||
|
fprintf(anim_file, "%d %d %d\n", num_frames_small, width_small, height_small);
|
|||
|
fprintf(anim_file, "%d\n", total_colors);
|
|||
|
|
|||
|
for ( i = 0; i < total_colors; i++ ) {
|
|||
|
fprintf(anim_file, "%x %x %x\n", cmap[i].red * 257,
|
|||
|
cmap[i].green * 257,
|
|||
|
cmap[i].blue * 257);
|
|||
|
}
|
|||
|
|
|||
|
if ( output_buf == NULL ) {
|
|||
|
error("No image data to write.\n");
|
|||
|
}
|
|||
|
|
|||
|
if ( fwrite(output_buf, sizeof(uchar_t), output_len, anim_file) !=
|
|||
|
output_len) {
|
|||
|
perror(ANIMATION_FILENAME);
|
|||
|
exit(errno);
|
|||
|
}
|
|||
|
|
|||
|
if ( fclose(anim_file) != 0 ) {
|
|||
|
perror(ANIMATION_FILENAME);
|
|||
|
exit(errno);
|
|||
|
}
|
|||
|
|
|||
|
printf("Wrote %d large frames, %d small frames.\n", num_frames_large,
|
|||
|
num_frames_small);
|
|||
|
|
|||
|
printf("%d colors\n", total_colors);
|
|||
|
|
|||
|
fprintf(stderr, "Successfully wrote '%s'\n", ANIMATION_FILENAME);
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|