mirror of https://github.com/GNOME/gimp.git
Updated the gfli plug-in to the version on the registry and folded the patch
for the "chunk-type-7-bug" back in. --Sven
This commit is contained in:
parent
eface111d7
commit
63a96d867d
|
@ -1,3 +1,8 @@
|
|||
Mon May 18 20:30:44 MEST 1998 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* updated the gfli plug-in to the version on the registry and
|
||||
folded the "chunk-type-7-bug"-patch back in
|
||||
|
||||
Sun May 17 23:06:38 EDT 1998 Matthew Wilson <msw@gimp.org>
|
||||
|
||||
* app/app_procs.c: applied patch from Michael Sweet to correct
|
||||
|
@ -157,7 +162,7 @@ Sun May 3 22:10:05 EDT 1998 Matthew Wilson <msw@gimp.org>
|
|||
Sun May 3 00:24:31 MEST 1998 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* app/channels_dialog.c: minimalistic change to the interface,
|
||||
make it's possible to set the channel opacity to 100.0%
|
||||
makes it possible to set the channel opacity to 100.0%
|
||||
(was 99.0% before)
|
||||
|
||||
Sat May 2 14:31:46 PDT 1998 Manish Singh <yosh@gimp.org>
|
||||
|
|
|
@ -5,6 +5,8 @@ pluginlibdir = $(gimpplugindir)/plug-ins
|
|||
pluginlib_PROGRAMS = gfli
|
||||
|
||||
gfli_SOURCES = \
|
||||
fli.h \
|
||||
fli.c \
|
||||
gfli.c
|
||||
|
||||
INCLUDES = \
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* GFLI 1.0
|
||||
*
|
||||
* A gimp plug-in to read FLI and FLC movies.
|
||||
* A gimp plug-in to read and write FLI and FLC movies.
|
||||
*
|
||||
* Copyright (C) 1997 Jens Ch. Restemeier <jchrr@hrz.uni-bielefeld.de>
|
||||
* Copyright (C) 1998 Jens Ch. Restemeier <jchrr@hrz.uni-bielefeld.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -17,19 +17,16 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* This is a first loader for FLI and FLC movies. It uses as the same method as
|
||||
* the gif plug-in to store the animation (i.e. 1 layer/frame).
|
||||
*
|
||||
* Current disadvantages:
|
||||
* - All frames must share the same colormap. Maybe I add an option for
|
||||
* generating RGB images in the next version !
|
||||
* - Generates A LOT OF warnings.
|
||||
* - Consumes a lot of memory (See wish-list: use the original data or
|
||||
* compression).
|
||||
* - doesn't save movies (will be added to next version, depends on
|
||||
* feedback). You can save as animated GIF, of course...
|
||||
* - doesn't support palette changes between two frames.
|
||||
*
|
||||
* Wish-List:
|
||||
* - I'd like to have a different format for storing animations, so I can use
|
||||
|
@ -41,382 +38,142 @@
|
|||
* image, and stores modified frames compressed (suggestion: libpng).
|
||||
* - I'd like a way to store additional information about a image to it, for
|
||||
* example copyright stuff or a timecode.
|
||||
*
|
||||
* Ideas:
|
||||
* - I could put all the functions for loading / saving fli into a
|
||||
* gimp-independant library. Anybody interested to save fli from his
|
||||
* application ?
|
||||
*
|
||||
* - I've thought about a small utility to mix MIDI events as custom chunks
|
||||
* between the FLI chunks. Anyone interested in implementing this ?
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "gtk/gtk.h"
|
||||
#include "libgimp/gimp.h"
|
||||
|
||||
static void query (void);
|
||||
static void run (char *name,
|
||||
int nparams,
|
||||
GParam *param,
|
||||
int *nreturn_vals,
|
||||
GParam **return_vals);
|
||||
gint32 load_image (char *filename);
|
||||
#include "fli.h"
|
||||
|
||||
GPlugInInfo PLUG_IN_INFO =
|
||||
{
|
||||
static void query (void);
|
||||
static void run (gchar *name, gint nparams, GParam *param, gint *nreturn_vals, GParam **return_vals);
|
||||
|
||||
static gint32 load_image (gchar *filename);
|
||||
static void save_image (gchar *filename, gint32 image);
|
||||
|
||||
GPlugInInfo PLUG_IN_INFO = {
|
||||
NULL, /* init_proc */
|
||||
NULL, /* quit_proc */
|
||||
query, /* query_proc */
|
||||
run, /* run_proc */
|
||||
};
|
||||
|
||||
GParamDef load_args[] = {
|
||||
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" },
|
||||
{ PARAM_STRING, "filename", "The name of the file to load" },
|
||||
{ PARAM_STRING, "raw_filename", "The name entered" },
|
||||
};
|
||||
GParamDef load_return_vals[] = {
|
||||
{ PARAM_IMAGE, "image", "Output image" },
|
||||
};
|
||||
gint nload_args = sizeof (load_args) / sizeof (load_args[0]);
|
||||
gint nload_return_vals = sizeof (load_return_vals) / sizeof (load_return_vals[0]);
|
||||
|
||||
GParamDef save_args[] = {
|
||||
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" },
|
||||
{ PARAM_IMAGE, "image", "Input image (unused)" },
|
||||
{ PARAM_DRAWABLE, "drawable", "Input drawable" },
|
||||
{ PARAM_STRING, "filename", "The name of the file to save" },
|
||||
{ PARAM_STRING, "raw_filename", "The name entered" },
|
||||
};
|
||||
GParamDef save_return_vals[] = {
|
||||
};
|
||||
gint nsave_args = sizeof (save_args) / sizeof (save_args[0]);
|
||||
gint nsave_return_vals = sizeof (save_return_vals) / sizeof (save_return_vals[0]);
|
||||
|
||||
MAIN ()
|
||||
|
||||
static void
|
||||
query ()
|
||||
static void query ()
|
||||
{
|
||||
static GParamDef load_args[] =
|
||||
{
|
||||
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" },
|
||||
{ PARAM_STRING, "filename", "The name of the file to load" },
|
||||
{ PARAM_STRING, "raw_filename", "The name entered" },
|
||||
};
|
||||
static GParamDef load_return_vals[] =
|
||||
{
|
||||
{ PARAM_IMAGE, "image", "Output image" },
|
||||
};
|
||||
static int nload_args = sizeof (load_args) / sizeof (load_args[0]);
|
||||
static int nload_return_vals = sizeof (load_return_vals) / sizeof (load_return_vals[0]);
|
||||
gimp_install_procedure (
|
||||
"file_fli_load",
|
||||
"load FLI-movies",
|
||||
"This is a experimantal plug-in to handle FLI movies",
|
||||
"Jens Ch. Restemeier",
|
||||
"Jens Ch. Restemeier",
|
||||
"1997",
|
||||
"<Load>/FLI",
|
||||
NULL,
|
||||
PROC_PLUG_IN,
|
||||
nload_args, nload_return_vals,
|
||||
load_args, load_return_vals);
|
||||
gimp_register_magic_load_handler ("file_fli_load", "fli", "", "4,byte,0x11,4,byte,0x12,5,byte,0xAF");
|
||||
|
||||
gimp_install_procedure ("file_fli_load",
|
||||
"load AA-movies",
|
||||
"This is a experimantal plug-in to handle FLI movies",
|
||||
"Jens Ch. Restemeier",
|
||||
"Jens Ch. Restemeier",
|
||||
"1997",
|
||||
"<Load>/FLI",
|
||||
NULL,
|
||||
PROC_PLUG_IN,
|
||||
nload_args, nload_return_vals,
|
||||
load_args, load_return_vals);
|
||||
|
||||
gimp_register_magic_load_handler ("file_fli_load", "fli,flc", "", "4,short,0x11af,4,short,0x12af");
|
||||
gimp_install_procedure (
|
||||
"file_fli_save",
|
||||
"save FLI-movies",
|
||||
"This is a experimantal plug-in to handle FLI movies",
|
||||
"Jens Ch. Restemeier",
|
||||
"Jens Ch. Restemeier",
|
||||
"1997",
|
||||
"<Save>/FLI",
|
||||
"INDEXED,GRAY",
|
||||
PROC_PLUG_IN,
|
||||
nsave_args, nsave_return_vals,
|
||||
save_args, save_return_vals);
|
||||
gimp_register_save_handler ("file_fli_save", "fli", "");
|
||||
}
|
||||
|
||||
static void
|
||||
run (char *name,
|
||||
int nparams,
|
||||
GParam *param,
|
||||
int *nreturn_vals,
|
||||
GParam **return_vals)
|
||||
GParam values[2];
|
||||
|
||||
void run (gchar *name, gint nparams, GParam *param, gint *nreturn_vals, GParam **return_vals)
|
||||
{
|
||||
static GParam values[2];
|
||||
GRunModeType run_mode;
|
||||
gint32 image_ID;
|
||||
GRunModeType run_mode;
|
||||
gint32 image_ID;
|
||||
|
||||
run_mode = param[0].data.d_int32;
|
||||
run_mode = param[0].data.d_int32;
|
||||
|
||||
*nreturn_vals = 1;
|
||||
*return_vals = values;
|
||||
values[0].type = PARAM_STATUS;
|
||||
values[0].data.d_status = STATUS_CALLING_ERROR;
|
||||
*nreturn_vals = 1;
|
||||
*return_vals = values;
|
||||
values[0].type = PARAM_STATUS;
|
||||
values[0].data.d_status = STATUS_CALLING_ERROR;
|
||||
|
||||
if (strcmp (name, "file_fli_load") == 0)
|
||||
{
|
||||
image_ID = load_image (param[1].data.d_string);
|
||||
if (strcmp (name, "file_fli_load") == 0) {
|
||||
image_ID = load_image (param[1].data.d_string);
|
||||
|
||||
if (image_ID != -1)
|
||||
{
|
||||
*nreturn_vals = 2;
|
||||
values[0].data.d_status = STATUS_SUCCESS;
|
||||
values[1].type = PARAM_IMAGE;
|
||||
values[1].data.d_image = image_ID;
|
||||
}
|
||||
else
|
||||
{
|
||||
values[0].data.d_status = STATUS_EXECUTION_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct _fli_header {
|
||||
unsigned long filesize;
|
||||
unsigned short magic;
|
||||
unsigned short frames;
|
||||
unsigned short width;
|
||||
unsigned short height;
|
||||
unsigned short depth;
|
||||
unsigned short flags;
|
||||
unsigned long speed;
|
||||
} s_fli_header;
|
||||
|
||||
typedef struct _fli_frame {
|
||||
unsigned long framesize;
|
||||
unsigned short magic;
|
||||
unsigned short chunks;
|
||||
} s_fli_frame;
|
||||
|
||||
/* read byte/word/long */
|
||||
inline unsigned char fli_read_char(FILE *f)
|
||||
{
|
||||
unsigned char b;
|
||||
fread(&b,1,1,f);
|
||||
return b;
|
||||
}
|
||||
|
||||
inline unsigned short fli_read_short(FILE *f)
|
||||
{
|
||||
unsigned char b[2];
|
||||
fread(&b,1,2,f);
|
||||
return (unsigned short)(b[1]<<8) | b[0];
|
||||
}
|
||||
|
||||
inline unsigned long fli_read_long(FILE *f)
|
||||
{
|
||||
unsigned char b[4];
|
||||
fread(&b,1,4,f);
|
||||
return (unsigned long)(b[3]<<24) | (b[2]<<16) | (b[1]<<8) | b[0];
|
||||
}
|
||||
|
||||
void fli_read_header(FILE *f, s_fli_header *fli_header)
|
||||
{
|
||||
fli_header->filesize=fli_read_long(f); /* 0 */
|
||||
fli_header->magic=fli_read_short(f); /* 4 */
|
||||
fli_header->frames=fli_read_short(f); /* 6 */
|
||||
fli_header->width=fli_read_short(f); /* 8 */
|
||||
fli_header->height=fli_read_short(f); /* 10 */
|
||||
fli_header->depth=fli_read_short(f); /* 12 */
|
||||
fli_header->flags=fli_read_short(f); /* 14 */
|
||||
if (fli_header->magic == 0xAF11) { /* FLI */
|
||||
/* FLI saves speed in 1/70s */
|
||||
fli_header->speed=fli_read_short(f)*14; /* 16 */
|
||||
} else {
|
||||
if (fli_header->magic == 0xAF12) { /* FLC */
|
||||
/* FLC saves speed in 1/1000s */
|
||||
fli_header->speed=fli_read_long(f); /* 16 */
|
||||
if (image_ID != -1) {
|
||||
*nreturn_vals = 2;
|
||||
values[0].data.d_status = STATUS_SUCCESS;
|
||||
values[1].type = PARAM_IMAGE;
|
||||
values[1].data.d_image = image_ID;
|
||||
} else {
|
||||
fprintf(stderr, "error: magic number is wrong !\n");
|
||||
values[0].data.d_status = STATUS_EXECUTION_ERROR;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (strcmp (name, "file_fli_save") == 0) {
|
||||
if (param[1].type == PARAM_IMAGE) {
|
||||
save_image (param[3].data.d_string, param[1].data.d_image);
|
||||
*nreturn_vals = 1;
|
||||
values[0].data.d_status = STATUS_SUCCESS;
|
||||
} else {
|
||||
values[0].data.d_status = STATUS_EXECUTION_ERROR;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void fli_read_frame(FILE *f, s_fli_header *fli_header, guchar *framebuf, guchar *cmap)
|
||||
{
|
||||
s_fli_frame fli_frame;
|
||||
unsigned long framepos;
|
||||
int c;
|
||||
unsigned short col_pos;
|
||||
col_pos=0;
|
||||
framepos=ftell(f);
|
||||
|
||||
fli_frame.framesize=fli_read_long(f);
|
||||
fli_frame.magic=fli_read_short(f);
|
||||
fli_frame.chunks=fli_read_short(f);
|
||||
|
||||
if (fli_frame.magic == 0xF1FA) {
|
||||
fseek(f, framepos+16, SEEK_SET);
|
||||
for (c=0;c<fli_frame.chunks;c++) {
|
||||
unsigned long chunkpos, chunksize;
|
||||
unsigned short chunktype;
|
||||
chunkpos = ftell(f);
|
||||
chunksize=fli_read_long(f);
|
||||
chunktype=fli_read_short(f);
|
||||
switch (chunktype) {
|
||||
case 11 : { /* fli_color */
|
||||
unsigned short num_packets;
|
||||
int cnt_packets;
|
||||
num_packets=fli_read_short(f);
|
||||
for (cnt_packets=num_packets; cnt_packets>0; cnt_packets--) {
|
||||
unsigned short skip_col, num_col, col_cnt;
|
||||
skip_col=fli_read_char(f);
|
||||
num_col=fli_read_char(f);
|
||||
if (num_col == 0) {
|
||||
for (col_pos=0; col_pos<768; col_pos++) {
|
||||
cmap[col_pos]=fli_read_char(f)<<2;
|
||||
}
|
||||
} else {
|
||||
col_pos+=(skip_col*3);
|
||||
for (col_cnt=num_col; (col_cnt>0) && (col_pos<768); col_cnt--) {
|
||||
cmap[col_pos++]=fli_read_char(f)<<2;
|
||||
cmap[col_pos++]=fli_read_char(f)<<2;
|
||||
cmap[col_pos++]=fli_read_char(f)<<2;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 13 : /* fli_black */
|
||||
memset(framebuf, 0, fli_header->width * fli_header->height);
|
||||
break;
|
||||
case 15 : { /* fli_brun */
|
||||
unsigned short yc;
|
||||
guchar *pos;
|
||||
for (yc=0; yc< fli_header->height; yc++) {
|
||||
unsigned short xc, pc, pcnt;
|
||||
pc=fli_read_char(f);
|
||||
xc=0;
|
||||
pos=framebuf+(fli_header->width * yc);
|
||||
for (pcnt=pc; pcnt>0; pcnt --) {
|
||||
unsigned short ps;
|
||||
ps=fli_read_char(f);
|
||||
|
||||
if (ps & 0x80) {
|
||||
unsigned short len;
|
||||
ps^=0xFF;
|
||||
ps+=1;
|
||||
for (len=ps; len>0; len--) {
|
||||
pos[xc++]=fli_read_char(f);
|
||||
}
|
||||
} else {
|
||||
unsigned char val;
|
||||
val=fli_read_char(f);
|
||||
memset(&(pos[xc]), val, ps);
|
||||
xc+=ps;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 16 : { /* fli_copy */
|
||||
unsigned long cc;
|
||||
guchar *pos;
|
||||
pos=framebuf;
|
||||
for (cc=fli_header->width * fli_header->height; cc>0; cc--) {
|
||||
*(pos++)=fli_read_char(f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 12 : { /* fli_lc */
|
||||
unsigned short yc, firstline, numline;
|
||||
guchar *pos;
|
||||
firstline = fli_read_short(f);
|
||||
numline = fli_read_short(f);
|
||||
for (yc=0; yc < numline; yc++) {
|
||||
unsigned short xc, pc, pcnt;
|
||||
pc=fli_read_char(f);
|
||||
xc=0;
|
||||
pos=framebuf+(fli_header->width * (firstline+yc));
|
||||
for (pcnt=pc; pcnt>0; pcnt --) {
|
||||
unsigned short ps,skip;
|
||||
skip=fli_read_char(f);
|
||||
ps=fli_read_char(f);
|
||||
xc+=skip;
|
||||
|
||||
if (ps & 0x80) {
|
||||
unsigned char val;
|
||||
ps^=0xFF;
|
||||
ps+=1;
|
||||
val=fli_read_char(f);
|
||||
memset(&(pos[xc]), val, ps);
|
||||
xc+=ps;
|
||||
} else {
|
||||
unsigned short len;
|
||||
for (len=ps; len>0; len--) {
|
||||
pos[xc++]=fli_read_char(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 7 : { /* fli_lc2 */
|
||||
unsigned short yc, lc, numline;
|
||||
guchar *pos;
|
||||
yc=0;
|
||||
numline = fli_read_short(f);
|
||||
for (lc=0; lc < numline; lc++) {
|
||||
unsigned short xc, pc, pcnt, lpf, lpn;
|
||||
pc=fli_read_short(f);
|
||||
lpf=0; lpn=0;
|
||||
while (pc & 0x8000) {
|
||||
if (pc & 0x4000) {
|
||||
/* yc+=pc & 0x3FFF; */ /* BANG! */
|
||||
yc+=0x10000-pc; /* better */
|
||||
} else {
|
||||
lpf=1;lpn=pc&0xFF;
|
||||
}
|
||||
pc=fli_read_short(f);
|
||||
}
|
||||
xc=0;
|
||||
pos=framebuf+(fli_header->width * yc);
|
||||
for (pcnt=pc; pcnt>0; pcnt --) {
|
||||
unsigned short ps,skip;
|
||||
skip=fli_read_char(f);
|
||||
ps=fli_read_char(f);
|
||||
xc+=skip;
|
||||
|
||||
if (ps & 0x80) {
|
||||
unsigned char v1,v2;
|
||||
ps^=0xFF;
|
||||
ps++;
|
||||
v1=fli_read_char(f);
|
||||
v2=fli_read_char(f);
|
||||
while (ps>0) {
|
||||
pos[xc++]=v1;
|
||||
pos[xc++]=v2;
|
||||
ps--;
|
||||
}
|
||||
} else {
|
||||
unsigned short len;
|
||||
for (len=ps; len>0; len--) {
|
||||
pos[xc++]=fli_read_char(f);
|
||||
pos[xc++]=fli_read_char(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lpf) pos[xc]=lpn;
|
||||
yc++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4 : { /* fli_color_2 */
|
||||
unsigned short num_packets;
|
||||
int cnt_packets;
|
||||
num_packets=fli_read_short(f);
|
||||
col_pos=0;
|
||||
for (cnt_packets=num_packets; cnt_packets>0; cnt_packets--) {
|
||||
unsigned short skip_col, num_col, col_cnt;
|
||||
skip_col=fli_read_char(f);
|
||||
num_col=fli_read_char(f);
|
||||
if (num_col == 0) {
|
||||
for (col_pos=0; col_pos<768; col_pos++) {
|
||||
cmap[col_pos]=fli_read_char(f);
|
||||
}
|
||||
} else {
|
||||
col_pos+=(skip_col+=3);
|
||||
for (col_cnt=num_col; (col_cnt>0) && (col_pos<768); col_cnt--) {
|
||||
cmap[col_pos++]=fli_read_char(f);
|
||||
cmap[col_pos++]=fli_read_char(f);
|
||||
cmap[col_pos++]=fli_read_char(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 18 : /* fli_mini (ignored) */ break;
|
||||
}
|
||||
if (chunksize & 1) chunksize++;
|
||||
fseek(f,chunkpos+chunksize,SEEK_SET);
|
||||
}
|
||||
}
|
||||
fseek(f, framepos+fli_frame.framesize, SEEK_SET);
|
||||
}
|
||||
|
||||
gint32 load_image (char *filename)
|
||||
/*
|
||||
* load fli animation and store as framestack
|
||||
*/
|
||||
gint32 load_image (gchar *filename)
|
||||
{
|
||||
FILE *f;
|
||||
char *name_buf;
|
||||
gchar *name_buf;
|
||||
GDrawable *drawable;
|
||||
gint32 image_ID, layer_ID;
|
||||
|
||||
guchar *frame_buffer;
|
||||
guchar cmap[768];
|
||||
gchar *fb, *ofb, *fb_x;
|
||||
gchar cm[768], ocm[768];
|
||||
GPixelRgn pixel_rgn;
|
||||
s_fli_header fli_header;
|
||||
|
||||
int cnt;
|
||||
gint cnt;
|
||||
|
||||
name_buf = g_malloc (64);
|
||||
|
||||
|
@ -425,7 +182,7 @@ gint32 load_image (char *filename)
|
|||
|
||||
f=fopen(filename ,"r");
|
||||
if (!f) {
|
||||
printf ("FLI: can't open \"%s\"\n", filename);
|
||||
fprintf (stderr, "FLI: can't open \"%s\"\n", filename);
|
||||
return -1;
|
||||
}
|
||||
fli_read_header(f, &fli_header);
|
||||
|
@ -434,30 +191,189 @@ gint32 load_image (char *filename)
|
|||
image_ID = gimp_image_new (fli_header.width, fli_header.height, INDEXED);
|
||||
gimp_image_set_filename (image_ID, filename);
|
||||
|
||||
frame_buffer=g_malloc(fli_header.width * fli_header.height);
|
||||
for (cnt=0; cnt< fli_header.frames; cnt++) {
|
||||
fb=g_malloc(fli_header.width * fli_header.height);
|
||||
ofb=g_malloc(fli_header.width * fli_header.height);
|
||||
for (cnt=0; cnt < fli_header.frames; cnt++) {
|
||||
sprintf(name_buf, "Frame (%i)",cnt+1);
|
||||
layer_ID = gimp_layer_new (
|
||||
image_ID, name_buf,
|
||||
fli_header.width, fli_header.height,
|
||||
INDEXED_IMAGE, 100, NORMAL_MODE);
|
||||
gimp_image_add_layer (image_ID, layer_ID, 0);
|
||||
gimp_image_add_layer (image_ID, layer_ID, cnt);
|
||||
|
||||
drawable = gimp_drawable_get (layer_ID);
|
||||
gimp_progress_update ((double) cnt / fli_header.frames);
|
||||
gimp_progress_update ((double) cnt / (double)fli_header.frames);
|
||||
|
||||
fli_read_frame(f, &fli_header, frame_buffer, cmap);
|
||||
fli_read_frame(f, &fli_header, ofb, ocm, fb, cm);
|
||||
|
||||
gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, fli_header.width, fli_header.height, TRUE, FALSE);
|
||||
gimp_pixel_rgn_set_rect (&pixel_rgn, frame_buffer, 0, 0, fli_header.width, fli_header.height);
|
||||
gimp_pixel_rgn_set_rect (&pixel_rgn, fb, 0, 0, fli_header.width, fli_header.height);
|
||||
|
||||
gimp_drawable_flush (drawable);
|
||||
gimp_drawable_detach (drawable);
|
||||
memcpy(ocm, cm, 768);
|
||||
fb_x=fb; fb=ofb; ofb=fb_x;
|
||||
}
|
||||
gimp_image_set_cmap (image_ID, cmap, 256);
|
||||
gimp_image_set_cmap (image_ID, cm, 256);
|
||||
fclose(f);
|
||||
|
||||
g_free (name_buf);
|
||||
g_free(frame_buffer);
|
||||
g_free(name_buf);
|
||||
g_free(fb);
|
||||
g_free(ofb);
|
||||
return image_ID;
|
||||
}
|
||||
|
||||
/*
|
||||
* get framestack and store as fli animation
|
||||
* (some code was taken from the GIF plugin.)
|
||||
*/
|
||||
void save_image(gchar *filename, gint32 image_ID)
|
||||
{
|
||||
FILE *f;
|
||||
gchar *name_buf;
|
||||
GDrawable *drawable;
|
||||
GDrawableType drawable_type;
|
||||
gint32 *framelist;
|
||||
gint nframes;
|
||||
|
||||
gchar *fb, *ofb;
|
||||
gchar cm[768];
|
||||
GPixelRgn pixel_rgn;
|
||||
s_fli_header fli_header;
|
||||
|
||||
gint cnt;
|
||||
|
||||
/*
|
||||
* prepare header and check information
|
||||
*/
|
||||
framelist = gimp_image_get_layers(image_ID, &nframes);
|
||||
drawable_type = gimp_drawable_type(framelist[0]);
|
||||
switch (drawable_type) {
|
||||
case INDEXEDA_IMAGE:
|
||||
case GRAYA_IMAGE:
|
||||
/* FIXME: should be a popup */
|
||||
fprintf (stderr, "FLI: Sorry, can't save images with Alpha.\n");
|
||||
return;
|
||||
break;
|
||||
case GRAY_IMAGE: {
|
||||
/* build grayscale palette */
|
||||
int i;
|
||||
for (i=0; i<256; i++) {
|
||||
cm[i*3+0]=cm[i*3+1]=cm[i*3+2]=i;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case INDEXED_IMAGE: {
|
||||
gint colors, i;
|
||||
gchar *cmap;
|
||||
cmap=gimp_image_get_cmap(image_ID, &colors);
|
||||
for (i=0; i<colors; i++) {
|
||||
cm[i*3+0]=cmap[i*3+0];
|
||||
cm[i*3+1]=cmap[i*3+1];
|
||||
cm[i*3+2]=cmap[i*3+2];
|
||||
}
|
||||
for (i=colors; i<256; i++) {
|
||||
cm[i*3+0]=cm[i*3+1]=cm[i*3+2]=i;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* FIXME: should be a popup */
|
||||
fprintf (stderr, "FLI: Sorry, I can save only INDEXED and GRAY images.\n");
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
name_buf = g_malloc (64);
|
||||
|
||||
sprintf (name_buf, "Saving %s:", filename);
|
||||
gimp_progress_init (name_buf);
|
||||
|
||||
/*
|
||||
* First build the fli header.
|
||||
*/
|
||||
fli_header.filesize=0; /* will be fixed when writing the header */
|
||||
fli_header.frames=0; /* will be fixed during the write */
|
||||
fli_header.width=gimp_image_width(image_ID);
|
||||
fli_header.height=gimp_image_height(image_ID);
|
||||
|
||||
if ((fli_header.width==320) && (fli_header.height=200)) {
|
||||
fli_header.magic=HEADER_FLI;
|
||||
} else {
|
||||
fli_header.magic=HEADER_FLC;
|
||||
}
|
||||
fli_header.depth=8; /* I've never seen a depth != 8 */
|
||||
fli_header.flags=3;
|
||||
fli_header.speed=1000/25;
|
||||
fli_header.created=0; /* program ID. not neccessary... */
|
||||
fli_header.updated=0; /* date in MS-DOS format. ignore...*/
|
||||
fli_header.aspect_x=1; /* aspect ratio. Will be added as soon.. */
|
||||
fli_header.aspect_y=1; /* ... as GIMP supports it. */
|
||||
|
||||
f=fopen(filename ,"w");
|
||||
if (!f) {
|
||||
fprintf (stderr, "FLI: can't open \"%s\"\n", filename);
|
||||
}
|
||||
fseek(f,128,SEEK_SET);
|
||||
|
||||
fb=g_malloc(fli_header.width * fli_header.height);
|
||||
ofb=g_malloc(fli_header.width * fli_header.height);
|
||||
/*
|
||||
* Now write all frames
|
||||
*/
|
||||
for (cnt=0; cnt<nframes; cnt++) {
|
||||
gint offset_x, offset_y, xc, yc;
|
||||
guint rows, cols, rowstride;
|
||||
gchar *tmp;
|
||||
|
||||
gimp_progress_update ((double) cnt / (double)nframes);
|
||||
|
||||
/* get layer data from GIMP */
|
||||
drawable = gimp_drawable_get (framelist[cnt]);
|
||||
gimp_drawable_offsets (framelist[cnt], &offset_x, &offset_y);
|
||||
cols = drawable->width;
|
||||
rows = drawable->height;
|
||||
rowstride = drawable->width;
|
||||
gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, drawable->width, drawable->height, FALSE, FALSE);
|
||||
tmp=malloc(cols * rows);
|
||||
gimp_pixel_rgn_get_rect (&pixel_rgn, tmp, 0, 0, drawable->width, drawable->height);
|
||||
|
||||
/* now paste it into the framebuffer, with the neccessary offset */
|
||||
for (yc=0; yc<cols; yc++) {
|
||||
int yy;
|
||||
yy=yc+offset_y;
|
||||
if ((yy>0) && (yy<fli_header.height)) {
|
||||
for (xc=0; xc<cols; xc++) {
|
||||
int xx;
|
||||
xx=xc+offset_x;
|
||||
if ((xx>0) && (xx<fli_header.width)) {
|
||||
fb[yy*fli_header.width + xx]=tmp[yc*cols+xc];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(tmp);
|
||||
|
||||
/* save the frame */
|
||||
if (cnt>0) {
|
||||
/* save frame, allow all codecs */
|
||||
fli_write_frame(f, &fli_header, ofb, cm, fb, cm, W_ALL);
|
||||
} else {
|
||||
/* save first frame, no delta information, allow all codecs */
|
||||
fli_write_frame(f, &fli_header, NULL, NULL, fb, cm, W_ALL);
|
||||
}
|
||||
memcpy(ofb, fb, fli_header.width * fli_header.height);
|
||||
}
|
||||
|
||||
/*
|
||||
* finish fli
|
||||
*/
|
||||
fli_write_header(f, &fli_header);
|
||||
fclose(f);
|
||||
|
||||
g_free(name_buf);
|
||||
g_free(fb);
|
||||
g_free(ofb);
|
||||
g_free(framelist);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue