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>
|
Sun May 17 23:06:38 EDT 1998 Matthew Wilson <msw@gimp.org>
|
||||||
|
|
||||||
* app/app_procs.c: applied patch from Michael Sweet to correct
|
* 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>
|
Sun May 3 00:24:31 MEST 1998 Sven Neumann <sven@gimp.org>
|
||||||
|
|
||||||
* app/channels_dialog.c: minimalistic change to the interface,
|
* 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)
|
(was 99.0% before)
|
||||||
|
|
||||||
Sat May 2 14:31:46 PDT 1998 Manish Singh <yosh@gimp.org>
|
Sat May 2 14:31:46 PDT 1998 Manish Singh <yosh@gimp.org>
|
||||||
|
|
|
@ -5,6 +5,8 @@ pluginlibdir = $(gimpplugindir)/plug-ins
|
||||||
pluginlib_PROGRAMS = gfli
|
pluginlib_PROGRAMS = gfli
|
||||||
|
|
||||||
gfli_SOURCES = \
|
gfli_SOURCES = \
|
||||||
|
fli.h \
|
||||||
|
fli.c \
|
||||||
gfli.c
|
gfli.c
|
||||||
|
|
||||||
INCLUDES = \
|
INCLUDES = \
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
/*
|
/*
|
||||||
* GFLI 1.0
|
* 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
|
* 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
|
* 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
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* 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
|
* 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).
|
* the gif plug-in to store the animation (i.e. 1 layer/frame).
|
||||||
*
|
*
|
||||||
* Current disadvantages:
|
* 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.
|
* - Generates A LOT OF warnings.
|
||||||
* - Consumes a lot of memory (See wish-list: use the original data or
|
* - Consumes a lot of memory (See wish-list: use the original data or
|
||||||
* compression).
|
* compression).
|
||||||
* - doesn't save movies (will be added to next version, depends on
|
* - doesn't support palette changes between two frames.
|
||||||
* feedback). You can save as animated GIF, of course...
|
|
||||||
*
|
*
|
||||||
* Wish-List:
|
* Wish-List:
|
||||||
* - I'd like to have a different format for storing animations, so I can use
|
* - 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).
|
* image, and stores modified frames compressed (suggestion: libpng).
|
||||||
* - I'd like a way to store additional information about a image to it, for
|
* - I'd like a way to store additional information about a image to it, for
|
||||||
* example copyright stuff or a timecode.
|
* example copyright stuff or a timecode.
|
||||||
*
|
* - I've thought about a small utility to mix MIDI events as custom chunks
|
||||||
* Ideas:
|
* between the FLI chunks. Anyone interested in implementing this ?
|
||||||
* - I could put all the functions for loading / saving fli into a
|
|
||||||
* gimp-independant library. Anybody interested to save fli from his
|
|
||||||
* application ?
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include "gtk/gtk.h"
|
#include "gtk/gtk.h"
|
||||||
#include "libgimp/gimp.h"
|
#include "libgimp/gimp.h"
|
||||||
|
|
||||||
static void query (void);
|
#include "fli.h"
|
||||||
static void run (char *name,
|
|
||||||
int nparams,
|
|
||||||
GParam *param,
|
|
||||||
int *nreturn_vals,
|
|
||||||
GParam **return_vals);
|
|
||||||
gint32 load_image (char *filename);
|
|
||||||
|
|
||||||
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, /* init_proc */
|
||||||
NULL, /* quit_proc */
|
NULL, /* quit_proc */
|
||||||
query, /* query_proc */
|
query, /* query_proc */
|
||||||
run, /* run_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 ()
|
MAIN ()
|
||||||
|
|
||||||
static void
|
static void query ()
|
||||||
query ()
|
|
||||||
{
|
{
|
||||||
static GParamDef load_args[] =
|
gimp_install_procedure (
|
||||||
{
|
"file_fli_load",
|
||||||
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" },
|
"load FLI-movies",
|
||||||
{ PARAM_STRING, "filename", "The name of the file to load" },
|
"This is a experimantal plug-in to handle FLI movies",
|
||||||
{ PARAM_STRING, "raw_filename", "The name entered" },
|
"Jens Ch. Restemeier",
|
||||||
};
|
"Jens Ch. Restemeier",
|
||||||
static GParamDef load_return_vals[] =
|
"1997",
|
||||||
{
|
"<Load>/FLI",
|
||||||
{ PARAM_IMAGE, "image", "Output image" },
|
NULL,
|
||||||
};
|
PROC_PLUG_IN,
|
||||||
static int nload_args = sizeof (load_args) / sizeof (load_args[0]);
|
nload_args, nload_return_vals,
|
||||||
static int nload_return_vals = sizeof (load_return_vals) / sizeof (load_return_vals[0]);
|
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",
|
gimp_install_procedure (
|
||||||
"load AA-movies",
|
"file_fli_save",
|
||||||
"This is a experimantal plug-in to handle FLI movies",
|
"save FLI-movies",
|
||||||
"Jens Ch. Restemeier",
|
"This is a experimantal plug-in to handle FLI movies",
|
||||||
"Jens Ch. Restemeier",
|
"Jens Ch. Restemeier",
|
||||||
"1997",
|
"Jens Ch. Restemeier",
|
||||||
"<Load>/FLI",
|
"1997",
|
||||||
NULL,
|
"<Save>/FLI",
|
||||||
PROC_PLUG_IN,
|
"INDEXED,GRAY",
|
||||||
nload_args, nload_return_vals,
|
PROC_PLUG_IN,
|
||||||
load_args, load_return_vals);
|
nsave_args, nsave_return_vals,
|
||||||
|
save_args, save_return_vals);
|
||||||
gimp_register_magic_load_handler ("file_fli_load", "fli,flc", "", "4,short,0x11af,4,short,0x12af");
|
gimp_register_save_handler ("file_fli_save", "fli", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
GParam values[2];
|
||||||
run (char *name,
|
|
||||||
int nparams,
|
void run (gchar *name, gint nparams, GParam *param, gint *nreturn_vals, GParam **return_vals)
|
||||||
GParam *param,
|
|
||||||
int *nreturn_vals,
|
|
||||||
GParam **return_vals)
|
|
||||||
{
|
{
|
||||||
static GParam values[2];
|
GRunModeType run_mode;
|
||||||
GRunModeType run_mode;
|
gint32 image_ID;
|
||||||
gint32 image_ID;
|
|
||||||
|
|
||||||
run_mode = param[0].data.d_int32;
|
run_mode = param[0].data.d_int32;
|
||||||
|
|
||||||
*nreturn_vals = 1;
|
*nreturn_vals = 1;
|
||||||
*return_vals = values;
|
*return_vals = values;
|
||||||
values[0].type = PARAM_STATUS;
|
values[0].type = PARAM_STATUS;
|
||||||
values[0].data.d_status = STATUS_CALLING_ERROR;
|
values[0].data.d_status = STATUS_CALLING_ERROR;
|
||||||
|
|
||||||
if (strcmp (name, "file_fli_load") == 0)
|
if (strcmp (name, "file_fli_load") == 0) {
|
||||||
{
|
image_ID = load_image (param[1].data.d_string);
|
||||||
image_ID = load_image (param[1].data.d_string);
|
|
||||||
|
|
||||||
if (image_ID != -1)
|
if (image_ID != -1) {
|
||||||
{
|
*nreturn_vals = 2;
|
||||||
*nreturn_vals = 2;
|
values[0].data.d_status = STATUS_SUCCESS;
|
||||||
values[0].data.d_status = STATUS_SUCCESS;
|
values[1].type = PARAM_IMAGE;
|
||||||
values[1].type = PARAM_IMAGE;
|
values[1].data.d_image = image_ID;
|
||||||
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 */
|
|
||||||
} else {
|
} 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)
|
/*
|
||||||
{
|
* load fli animation and store as framestack
|
||||||
s_fli_frame fli_frame;
|
*/
|
||||||
unsigned long framepos;
|
gint32 load_image (gchar *filename)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char *name_buf;
|
gchar *name_buf;
|
||||||
GDrawable *drawable;
|
GDrawable *drawable;
|
||||||
gint32 image_ID, layer_ID;
|
gint32 image_ID, layer_ID;
|
||||||
|
|
||||||
guchar *frame_buffer;
|
gchar *fb, *ofb, *fb_x;
|
||||||
guchar cmap[768];
|
gchar cm[768], ocm[768];
|
||||||
GPixelRgn pixel_rgn;
|
GPixelRgn pixel_rgn;
|
||||||
s_fli_header fli_header;
|
s_fli_header fli_header;
|
||||||
|
|
||||||
int cnt;
|
gint cnt;
|
||||||
|
|
||||||
name_buf = g_malloc (64);
|
name_buf = g_malloc (64);
|
||||||
|
|
||||||
|
@ -425,7 +182,7 @@ gint32 load_image (char *filename)
|
||||||
|
|
||||||
f=fopen(filename ,"r");
|
f=fopen(filename ,"r");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
printf ("FLI: can't open \"%s\"\n", filename);
|
fprintf (stderr, "FLI: can't open \"%s\"\n", filename);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fli_read_header(f, &fli_header);
|
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);
|
image_ID = gimp_image_new (fli_header.width, fli_header.height, INDEXED);
|
||||||
gimp_image_set_filename (image_ID, filename);
|
gimp_image_set_filename (image_ID, filename);
|
||||||
|
|
||||||
frame_buffer=g_malloc(fli_header.width * fli_header.height);
|
fb=g_malloc(fli_header.width * fli_header.height);
|
||||||
for (cnt=0; cnt< fli_header.frames; cnt++) {
|
ofb=g_malloc(fli_header.width * fli_header.height);
|
||||||
|
for (cnt=0; cnt < fli_header.frames; cnt++) {
|
||||||
sprintf(name_buf, "Frame (%i)",cnt+1);
|
sprintf(name_buf, "Frame (%i)",cnt+1);
|
||||||
layer_ID = gimp_layer_new (
|
layer_ID = gimp_layer_new (
|
||||||
image_ID, name_buf,
|
image_ID, name_buf,
|
||||||
fli_header.width, fli_header.height,
|
fli_header.width, fli_header.height,
|
||||||
INDEXED_IMAGE, 100, NORMAL_MODE);
|
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);
|
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_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_flush (drawable);
|
||||||
gimp_drawable_detach (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);
|
fclose(f);
|
||||||
|
|
||||||
g_free (name_buf);
|
g_free(name_buf);
|
||||||
g_free(frame_buffer);
|
g_free(fb);
|
||||||
|
g_free(ofb);
|
||||||
return image_ID;
|
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