summaryrefslogtreecommitdiffstats
path: root/kernel/kls_fli
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-24 17:43:19 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-24 17:43:19 +0000
commit0292059f4a16434600564cfa3f0ad2309a508a54 (patch)
treed95953cd53011917c4df679b96aedca39401b54f /kernel/kls_fli
downloadlibksquirrel-0292059f4a16434600564cfa3f0ad2309a508a54.tar.gz
libksquirrel-0292059f4a16434600564cfa3f0ad2309a508a54.zip
Added libksquirrel for KDE3
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/libraries/libksquirrel@1095624 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kernel/kls_fli')
-rw-r--r--kernel/kls_fli/Makefile.am9
-rw-r--r--kernel/kls_fli/fmt_codec_fli.cpp449
-rw-r--r--kernel/kls_fli/fmt_codec_fli_defs.h92
3 files changed, 550 insertions, 0 deletions
diff --git a/kernel/kls_fli/Makefile.am b/kernel/kls_fli/Makefile.am
new file mode 100644
index 0000000..7570336
--- /dev/null
+++ b/kernel/kls_fli/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_fli.la
+
+libkls_fli_la_SOURCES = fmt_codec_fli.cpp fmt_codec_fli_defs.h
+
+libkls_fli_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_fli_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_fli/fmt_codec_fli.cpp b/kernel/kls_fli/fmt_codec_fli.cpp
new file mode 100644
index 0000000..d186d98
--- /dev/null
+++ b/kernel/kls_fli/fmt_codec_fli.cpp
@@ -0,0 +1,449 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_fli_defs.h"
+#include "fmt_codec_fli.h"
+
+#include "../xpm/codec_fli.xpm"
+
+/*
+ *
+ * The FLI file format (sometimes called Flic)
+ * is one of the most popular
+ * animation formats found in the MS-DOS and Windows environments today. FLI is
+ * used widely in animation programs, computer games, and CAD applications
+ * requiring 3D manipulation of vector drawings. Flic, in common
+ * with most animation formats, does not support either audio or video data, but
+ * instead stores only sequences of still image data.
+ *
+ */
+
+// maximum number of frames in FLI is 1024
+#define MAX_FRAME 1024
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.3.2";
+ o->name = "FLI Animation";
+ o->filter = "*.fli ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "video/x-flic";
+ o->pixmap = codec_fli;
+ o->readable = true;
+ o->canbemultiple = true;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ if(!frs.readK(&flic, sizeof(FLICHEADER)))
+ return SQE_R_BADFILE;
+
+ if(flic.FileId != 0xAF11)// && flic.FileId != 0xAF12)
+ return SQE_R_BADFILE;
+
+ if(flic.Flags != 3)
+ cerr << "libSQ_read_fli: WARNING: Flags != 3" << endl;
+
+ memset(pal, 0, 768);
+
+ currentImage = -1;
+
+ buf = (u8**)calloc(flic.Height, sizeof(u8*));
+
+ if(!buf)
+ return SQE_R_NOMEMORY;
+
+ for(s32 i = 0;i < flic.Height;i++)
+ {
+ buf[i] = (u8*)0;
+ }
+
+ for(s32 i = 0;i < flic.Height;i++)
+ {
+ buf[i] = (u8*)calloc(flic.Width, sizeof(u8));
+
+ if(!buf[i])
+ return SQE_R_NOMEMORY;
+ }
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage == flic.NumberOfFrames || currentImage == MAX_FRAME)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ image.w = flic.Width;
+ image.h = flic.Height;
+ image.bpp = 8;
+ image.delay = (s32)((float)flic.FrameDelay * 14.3);
+ finfo.animated = (currentImage) ? true : false;
+
+// prs32f("%dx%d@%d, delay: %d\n", flic.Width, flic.Height, flic.PixelDepth, finfo.image[currentImage].delay);
+
+ CHUNKHEADER chunk;
+ CHUNKHEADER subchunk;
+ u16 subchunks;
+
+ fstream::pos_type pos = frs.tellg();
+// prs32f("POS AFTER HEADER: %d\n", pos);
+
+ while(true)
+ {
+ if(!skip_flood(frs))
+ return SQE_R_BADFILE;
+
+ if(!frs.readK(&chunk, sizeof(CHUNKHEADER)))
+ return SQE_R_BADFILE;
+
+// prs32f("Read MAIN chunk: size: %d, type: %X\n", chunk.size, chunk.type);
+
+ if(chunk.type != CHUNK_PREFIX_TYPE &&
+ chunk.type != CHUNK_SCRIPT_CHUNK &&
+ chunk.type != CHUNK_FRAME_TYPE &&
+ chunk.type != CHUNK_SEGMENT_TABLE &&
+ chunk.type != CHUNK_HUFFMAN_TABLE)
+ return SQE_R_BADFILE;
+
+ if(chunk.type != CHUNK_FRAME_TYPE)
+ frs.seekg(chunk.size - sizeof(CHUNKHEADER), ios::cur);
+ else
+ {
+ if(!frs.readK(&subchunks, sizeof(u16)))
+ return SQE_R_BADFILE;
+// prs32f("Chunk #%X has %d subchunks\n", chunk.type, subchunks);
+ frs.seekg(sizeof(u16) * 4, ios::cur);
+ break;
+ }
+ }
+
+// prs32f("POS MAIN: %d\n", ftell(fptr));
+// fsetpos(fptr, (fpos_t*)&pos);
+// fseek(fptr, chunk.size, SEEK_CUR);
+// prs32f("POS2 MAIN: %d\n", ftell(fptr));
+
+ while(subchunks--)
+ {
+ pos = frs.tellg();
+
+ if(!frs.readK(&subchunk, sizeof(CHUNKHEADER)))
+ return SQE_R_BADFILE;
+
+// prs32f("*** Subchunk: %d\n", subchunk.type);
+
+ switch(subchunk.type)
+ {
+ case CHUNK_COLOR_64:
+ case CHUNK_COLOR_256:
+ {
+// prs32f("*** Palette64 CHUNK\n");
+ u8 skip, count;
+ u16 packets;
+ RGB e;
+
+ if(!frs.readK(&packets, sizeof(u16)))
+ return SQE_R_BADFILE;
+// prs32f("COLOR_64 packets: %d\n", packets);
+
+ for(s32 i = 0;i < packets;i++)
+ {
+ if(!frs.readK(&skip, 1)) return SQE_R_BADFILE;
+ if(!frs.readK(&count, 1)) return SQE_R_BADFILE;
+// prs32f("COLOR64 skip: %d, count: %d\n", skip, count);
+
+ if(count)
+ {
+ for(s32 j = 0;j < count;j++)
+ {
+ if(!frs.readK(&e, sizeof(RGB))) return SQE_R_BADFILE;
+// prs32f("COLOR_64 PALLETTE CHANGE %d,%d,%d\n", e.r, e.g, e.b);
+ }
+ }
+ else
+ {
+// prs32f("Reading pallette...\n");
+ if(!frs.readK(pal, sizeof(RGB) * 256)) return SQE_R_BADFILE;
+
+ u8 *pp = (u8 *)pal;
+
+ if(subchunk.type == CHUNK_COLOR_64)
+ for(s32 j = 0;j < 768;j++)
+ pp[j] <<= 2;
+
+// for(s32 j = 0;j < 256;j++)
+// prs32f("COLOR_64 PALLETTE %d,%d,%d\n", pal[j].r, pal[j].g, pal[j].b);
+// prs32f("\n");
+ }
+ }
+ }
+ break;
+
+ case CHUNK_RLE:
+ {
+// prs32f("*** RLE DATA CHUNK\n");
+ u8 value;
+ s8 c;
+ s32 count;
+
+ for(s32 j = 0;j < image.h;j++)
+ {
+ s32 index = 0;
+ count = 0;
+ if(!frs.readK(&c, 1)) return SQE_R_BADFILE;
+
+ while(count < image.w)
+ {
+ if(!frs.readK(&c, 1)) return SQE_R_BADFILE;
+
+ if(c < 0)
+ {
+ c = -c;
+
+ for(s32 i = 0;i < c;i++)
+ {
+ if(!frs.readK(&value, 1)) return SQE_R_BADFILE;
+ buf[j][index] = value;
+ index++;
+ }
+
+ count += c;
+ }
+ else
+ {
+ if(!frs.readK(&value, 1)) return SQE_R_BADFILE;
+
+ for(s32 i = 0;i < c;i++)
+ {
+ buf[j][index] = value;
+ index++;
+ }
+
+ count += c;
+ }
+ }
+ }
+ }
+ break;
+
+ case CHUNK_DELTA_FLI:
+ {
+ u16 starty, totaly, ally, index;
+ u8 packets, skip, byte;
+ s8 size;
+ s32 count;
+
+ if(!frs.readK(&starty, 2)) return SQE_R_BADFILE;
+ if(!frs.readK(&totaly, 2)) return SQE_R_BADFILE;
+
+ ally = starty + totaly;
+
+// prs32f("Y: %d, Total: %d\n", starty, totaly);
+
+ for(s32 j = starty;j < ally;j++)
+ {
+ count = 0;
+ index = 0;
+
+ if(!frs.readK(&packets, 1)) return SQE_R_BADFILE;
+
+ while(count < image.w)
+ {
+ for(s32 k = 0;k < packets;k++)
+ {
+// prs32f("LINE %d\n", j);
+ if(!frs.readK(&skip, 1)) return SQE_R_BADFILE;
+ if(!frs.readK(&size, 1)) return SQE_R_BADFILE;
+
+ index += skip;
+
+// prs32f("SKIP: %d, SIZE: %d\n", skip, size);
+
+ if(size > 0)
+ {
+ if(!frs.readK(buf[j]+index, size)) return SQE_R_BADFILE;
+ }
+ else if(size < 0)
+ {
+ size = -size;
+ if(!frs.readK(&byte, 1)) return SQE_R_BADFILE;
+ memset(buf[j]+index, byte, size);
+ }
+
+ index += size;
+ count += size;
+ }
+
+ break;
+ }
+ }
+ }
+ break;
+
+ case CHUNK_BLACK:
+ break;
+
+ case CHUNK_COPY:
+ {
+// prs32f("*** COPY DATA CHUNK\n");
+
+ for(s32 j = 0;j < image.h;j++)
+ {
+ if(!frs.readK(buf[j], image.w)) return SQE_R_BADFILE;
+ }
+ }
+ break;
+
+ default:
+// prs32f("*** UNKNOWN CHUNK! SEEKING ANYWAY\n");
+ frs.seekg(pos);
+ frs.seekg(subchunk.size, ios::cur);
+ }
+
+// prs32f("POS: %d\n", ftell(fptr));
+// prs32f("POS2: %d\n", ftell(fptr));
+ }
+
+ image.compression = "RLE/DELTA_FLI";
+ image.colorspace = "Color indexed";
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ line = -1;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ line++;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ for(s32 i = 0;i < im->w;i++)
+ {
+ memcpy(scan+i, pal+buf[line][i], sizeof(RGB));
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(buf)
+ {
+ for(s32 i = 0;i < flic.Height;i++)
+ if(buf[i])
+ free(buf[i]);
+
+ free(buf);
+ }
+
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool find_chunk_type(const u16 type)
+{
+ static const u16 A[] =
+ {
+ CHUNK_PREFIX_TYPE,
+ CHUNK_SCRIPT_CHUNK,
+ CHUNK_FRAME_TYPE,
+ CHUNK_SEGMENT_TABLE,
+ CHUNK_HUFFMAN_TABLE
+ };
+
+ static const s32 S = 5;
+
+ for(s32 i = 0;i < S;i++)
+ if(type == A[i])
+ return true;
+
+ return false;
+}
+
+bool fmt_codec::skip_flood(ifstreamK &s)
+{
+ u8 _f[4];
+ u16 b;
+ fstream::pos_type _pos;
+
+// prs32f("SKIP_FLOOD pos: %d\n", ftell(f));
+
+ if(!s.readK(_f, 4)) return false;
+
+ do
+ {
+ _pos = s.tellg();
+ if(!s.readK(&b, 2)) return false;
+// prs32f("SKIP_FLOOD b: %X\n", b);
+ s.seekg(-1, ios::cur);
+ }while(!find_chunk_type(b));
+
+ _pos -= 4;
+
+ s.seekg(_pos);
+
+ return true;
+
+// prs32f("SKIP_FLOOD pos2: %d\n", ftell(f));
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_fli/fmt_codec_fli_defs.h b/kernel/kls_fli/fmt_codec_fli_defs.h
new file mode 100644
index 0000000..dd08b94
--- /dev/null
+++ b/kernel/kls_fli/fmt_codec_fli_defs.h
@@ -0,0 +1,92 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_fli
+#define KSQUIRREL_READ_IMAGE_fli
+
+struct FLICHEADER
+{
+ u32 FileSize; /* Total size of file */
+ u16 FileId; /* File format indicator */
+ u16 NumberOfFrames; /* Total number of frames */
+ u16 Width; /* Screen width in pixels */
+ u16 Height; /* Screen height in pixels */
+ u16 PixelDepth; /* Number of bits per pixel */
+ u16 Flags; /* Set to 03h */
+ u32 FrameDelay; /* Time delay between frames */
+ u16 Reserved1; /* Not used (Set to 00h) */
+
+// The following fields are set to 00h in a .FLI file
+ u32 DateCreated; /* Time/Date the file was created */
+ u32 CreatorSN; /* Serial number of creator program */
+ u32 LastUpdated; /* Time/Date the file last changed */
+ u32 UpdaterSN; /* Serial number of updater program */
+ u16 XAspect; /* X-axis of display aspect ratio */
+ u16 YAspect; /* Y-axis of display aspect ratio */
+ u8 Reserved2[38]; /* Not used (Set to 00h) */
+ u32 Frame1Offset; /* Offset of first frame */
+ u32 Frame2Offset; /* Offset of second frame */
+ u8 Reserved3[40]; /* Not used (Set to 00h) */
+
+}PACKED;
+
+struct CHUNKHEADER
+{
+ u32 size; /* Total size of chunk */
+ u16 type; /* Chunk identifier */
+// u16 subchunks; /* Number of subchunks in this chunk */
+// u8 res[8]; /* Not used (Set to 00h) */
+
+}PACKED;
+
+#define CHUNK_CEL_DATA 3
+#define CHUNK_COLOR_256 4
+#define CHUNK_DELTA_FLC 7
+#define CHUNK_COLOR_64 11
+#define CHUNK_DELTA_FLI 12
+#define CHUNK_BLACK 13
+#define CHUNK_RLE 15
+#define CHUNK_COPY 16
+#define CHUNK_PSTAMP 18
+#define CHUNK_DTA_BRUN 25
+#define CHUNK_DTA_COPY 26
+#define CHUNK_DTA_LC 27
+#define CHUNK_LABEL 31
+#define CHUNK_BMP_MASK 32
+#define CHUNK_MLEV_MASK 33
+#define CHUNK_SEGMENT 34
+#define CHUNK_KEY_IMAGE 35
+#define CHUNK_KEY_PAL 36
+#define CHUNK_REGION 37
+#define CHUNK_WAVE 38
+#define CHUNK_USERSTR 39
+#define CHUNK_RGN_MASK 40
+#define CHUNK_LABELEX 41
+#define CHUNK_SHIFT 42
+#define CHUNK_PATHMAP 43
+
+#define CHUNK_PREFIX_TYPE 0xF100
+#define CHUNK_SCRIPT_CHUNK 0xF1E0
+#define CHUNK_FRAME_TYPE 0xF1FA
+#define CHUNK_SEGMENT_TABLE 0xF1FB
+#define CHUNK_HUFFMAN_TABLE 0xF1FC
+
+#endif