Initial checkin of Pika from heckimp
This commit is contained in:
645
plug-ins/file-faxg3/faxg3.c
Normal file
645
plug-ins/file-faxg3/faxg3.c
Normal file
@ -0,0 +1,645 @@
|
||||
/* This is a plugin for PIKA.
|
||||
*
|
||||
* Copyright (C) 1997 Jochen Friedrich
|
||||
* Parts Copyright (C) 1995 Gert Doering
|
||||
* Parts Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <glib.h> /* For G_OS_WIN32 */
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#ifndef _O_BINARY
|
||||
#define _O_BINARY 0
|
||||
#endif
|
||||
|
||||
#include <libpika/pika.h>
|
||||
|
||||
#include "g3.h"
|
||||
|
||||
#include "libpika/stdplugins-intl.h"
|
||||
|
||||
|
||||
#define LOAD_PROC "file-faxg3-load"
|
||||
#define VERSION "0.6"
|
||||
|
||||
|
||||
typedef struct _Faxg3 Faxg3;
|
||||
typedef struct _Faxg3Class Faxg3Class;
|
||||
|
||||
struct _Faxg3
|
||||
{
|
||||
PikaPlugIn parent_instance;
|
||||
};
|
||||
|
||||
struct _Faxg3Class
|
||||
{
|
||||
PikaPlugInClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
#define FAXG3_TYPE (faxg3_get_type ())
|
||||
#define FAXG3 (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FAXG3_TYPE, Faxg3))
|
||||
|
||||
GType faxg3_get_type (void) G_GNUC_CONST;
|
||||
|
||||
static GList * faxg3_query_procedures (PikaPlugIn *plug_in);
|
||||
static PikaProcedure * faxg3_create_procedure (PikaPlugIn *plug_in,
|
||||
const gchar *name);
|
||||
|
||||
static PikaValueArray * faxg3_load (PikaProcedure *procedure,
|
||||
PikaRunMode run_mode,
|
||||
GFile *file,
|
||||
const PikaValueArray *args,
|
||||
gpointer run_data);
|
||||
|
||||
static PikaImage * load_image (GFile *file,
|
||||
GError **error);
|
||||
|
||||
static PikaImage * emitpika (gint hcol,
|
||||
gint row,
|
||||
const gchar *bitmap,
|
||||
gint bperrow,
|
||||
GFile *file,
|
||||
GError **error);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (Faxg3, faxg3, PIKA_TYPE_PLUG_IN)
|
||||
|
||||
PIKA_MAIN (FAXG3_TYPE)
|
||||
DEFINE_STD_SET_I18N
|
||||
|
||||
|
||||
static void
|
||||
faxg3_class_init (Faxg3Class *klass)
|
||||
{
|
||||
PikaPlugInClass *plug_in_class = PIKA_PLUG_IN_CLASS (klass);
|
||||
|
||||
plug_in_class->query_procedures = faxg3_query_procedures;
|
||||
plug_in_class->create_procedure = faxg3_create_procedure;
|
||||
plug_in_class->set_i18n = STD_SET_I18N;
|
||||
}
|
||||
|
||||
static void
|
||||
faxg3_init (Faxg3 *faxg3)
|
||||
{
|
||||
}
|
||||
|
||||
static GList *
|
||||
faxg3_query_procedures (PikaPlugIn *plug_in)
|
||||
{
|
||||
return g_list_append (NULL, g_strdup (LOAD_PROC));
|
||||
}
|
||||
|
||||
static PikaProcedure *
|
||||
faxg3_create_procedure (PikaPlugIn *plug_in,
|
||||
const gchar *name)
|
||||
{
|
||||
PikaProcedure *procedure = NULL;
|
||||
|
||||
if (! strcmp (name, LOAD_PROC))
|
||||
{
|
||||
procedure = pika_load_procedure_new (plug_in, name,
|
||||
PIKA_PDB_PROC_TYPE_PLUGIN,
|
||||
faxg3_load, NULL, NULL);
|
||||
|
||||
pika_procedure_set_menu_label (procedure, _("G3 fax image"));
|
||||
|
||||
pika_procedure_set_documentation (procedure,
|
||||
"Loads g3 fax files",
|
||||
"This plug-in loads Fax G3 Image files.",
|
||||
name);
|
||||
pika_procedure_set_attribution (procedure,
|
||||
"Jochen Friedrich",
|
||||
"Jochen Friedrich, Gert Doering, "
|
||||
"Spencer Kimball & Peter Mattis",
|
||||
NULL);
|
||||
|
||||
pika_file_procedure_set_mime_types (PIKA_FILE_PROCEDURE (procedure),
|
||||
"image/g3-fax");
|
||||
pika_file_procedure_set_extensions (PIKA_FILE_PROCEDURE (procedure),
|
||||
"g3");
|
||||
pika_file_procedure_set_magics (PIKA_FILE_PROCEDURE (procedure),
|
||||
"4,string,Research");
|
||||
}
|
||||
|
||||
return procedure;
|
||||
}
|
||||
|
||||
static PikaValueArray *
|
||||
faxg3_load (PikaProcedure *procedure,
|
||||
PikaRunMode run_mode,
|
||||
GFile *file,
|
||||
const PikaValueArray *args,
|
||||
gpointer run_data)
|
||||
{
|
||||
PikaValueArray *return_vals;
|
||||
PikaImage *image;
|
||||
GError *error = NULL;
|
||||
|
||||
gegl_init (NULL, NULL);
|
||||
|
||||
image = load_image (file, &error);
|
||||
|
||||
if (! image)
|
||||
return pika_procedure_new_return_values (procedure,
|
||||
PIKA_PDB_EXECUTION_ERROR,
|
||||
error);
|
||||
|
||||
return_vals = pika_procedure_new_return_values (procedure,
|
||||
PIKA_PDB_SUCCESS,
|
||||
NULL);
|
||||
|
||||
PIKA_VALUES_SET_IMAGE (return_vals, 1, image);
|
||||
|
||||
return return_vals;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
putbin (unsigned long d)
|
||||
{
|
||||
unsigned long i = 0x80000000;
|
||||
|
||||
while (i != 0)
|
||||
{
|
||||
putc((d & i) ? '1' : '0', stderr);
|
||||
i >>= 1;
|
||||
}
|
||||
putc('\n', stderr);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int byte_tab[256];
|
||||
/* static int o_stretch; */ /* -stretch: double each line */
|
||||
/* static int o_stretch_force=-1; */ /* -1: guess from filename */
|
||||
/* static int o_lj; */ /* -l: LJ output */
|
||||
/* static int o_turn; */ /* -t: turn 90 degrees right */
|
||||
|
||||
struct g3_tree * black, * white;
|
||||
|
||||
#define CHUNK 2048;
|
||||
static char rbuf[2048]; /* read buffer */
|
||||
static int rp; /* read pointer */
|
||||
static int rs; /* read buffer size */
|
||||
|
||||
#define MAX_ROWS 4300
|
||||
#define MAX_COLS 1728 /* !! FIXME - command line parameter */
|
||||
|
||||
|
||||
static PikaImage *
|
||||
load_image (GFile *file,
|
||||
GError **error)
|
||||
{
|
||||
int data;
|
||||
int hibit;
|
||||
struct g3_tree *p;
|
||||
int nr_pels;
|
||||
int fd;
|
||||
int color;
|
||||
int i, rr, rsize;
|
||||
int cons_eol;
|
||||
int last_eol_row;
|
||||
|
||||
PikaImage *image = NULL;
|
||||
gint bperrow = MAX_COLS/8; /* bytes per bit row */
|
||||
gchar *bitmap; /* MAX_ROWS by (bperrow) bytes */
|
||||
gchar *bp; /* bitmap pointer */
|
||||
gint row;
|
||||
gint max_rows; /* max. rows allocated */
|
||||
gint col, hcol; /* column, highest column ever used */
|
||||
|
||||
pika_progress_init_printf (_("Opening '%s'"),
|
||||
pika_file_get_utf8_name (file));
|
||||
|
||||
/* initialize lookup trees */
|
||||
build_tree (&white, t_white);
|
||||
build_tree (&white, m_white);
|
||||
build_tree (&black, t_black);
|
||||
build_tree (&black, m_black);
|
||||
|
||||
init_byte_tab (0, byte_tab);
|
||||
|
||||
fd = g_open (g_file_peek_path (file), O_RDONLY | _O_BINARY, 0);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
|
||||
_("Could not open '%s' for reading: %s"),
|
||||
pika_file_get_utf8_name (file), g_strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hibit = 0;
|
||||
data = 0;
|
||||
|
||||
cons_eol = 0; /* consecutive EOLs read - zero yet */
|
||||
last_eol_row = 0;
|
||||
|
||||
color = 0; /* start with white */
|
||||
rr = 0;
|
||||
|
||||
rsize = lseek (fd, 0L, SEEK_END);
|
||||
lseek (fd, 0L, 0);
|
||||
|
||||
rs = read (fd, rbuf, sizeof (rbuf));
|
||||
if (rs < 0)
|
||||
{
|
||||
perror ("read");
|
||||
close (fd);
|
||||
pika_quit ();
|
||||
}
|
||||
|
||||
rr += rs;
|
||||
pika_progress_update ((float) rr / rsize / 2.0);
|
||||
|
||||
/* skip GhostScript header */
|
||||
rp = (rs >= 64 && strcmp (rbuf + 1, "PC Research, Inc") == 0) ? 64 : 0;
|
||||
|
||||
/* initialize bitmap */
|
||||
|
||||
row = col = hcol = 0;
|
||||
|
||||
bitmap = g_new0 (gchar, (max_rows = MAX_ROWS) * MAX_COLS / 8);
|
||||
if (! bitmap)
|
||||
{
|
||||
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||
_("Could not create buffer to process image data."));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bp = &bitmap[row * MAX_COLS / 8];
|
||||
|
||||
while (rs > 0 && cons_eol < 10) /* i.e., while (!EOF) */
|
||||
{
|
||||
#ifdef DEBUG
|
||||
g_printerr ("hibit=%2d, data=", hibit);
|
||||
putbin (data);
|
||||
#endif
|
||||
|
||||
while (hibit < 20)
|
||||
{
|
||||
data |= (byte_tab[(int) (unsigned char) rbuf[rp++]] << hibit);
|
||||
hibit += 8;
|
||||
|
||||
if (rp >= rs)
|
||||
{
|
||||
rs = read (fd, rbuf, sizeof (rbuf));
|
||||
if (rs < 0)
|
||||
{ perror ("read2");
|
||||
break;
|
||||
}
|
||||
rr += rs;
|
||||
pika_progress_update ((float) rr / rsize / 2.0);
|
||||
rp = 0;
|
||||
if (rs == 0)
|
||||
goto do_write;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
g_printerr ("hibit=%2d, data=", hibit);
|
||||
putbin (data);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (color == 0) /* white */
|
||||
p = white->nextb[data & BITM];
|
||||
else /* black */
|
||||
p = black->nextb[data & BITM];
|
||||
|
||||
while (p != NULL && ! (p->nr_bits))
|
||||
{
|
||||
data >>= FBITS;
|
||||
hibit -= FBITS;
|
||||
p = p->nextb[data & BITM];
|
||||
}
|
||||
|
||||
if (p == NULL) /* invalid code */
|
||||
{
|
||||
g_printerr ("invalid code, row=%d, col=%d, file offset=%lx, skip to eol\n",
|
||||
row, col, (unsigned long) lseek (fd, 0, 1) - rs + rp);
|
||||
|
||||
while ((data & 0x03f) != 0)
|
||||
{
|
||||
data >>= 1; hibit--;
|
||||
|
||||
if ( hibit < 20 )
|
||||
{
|
||||
data |= (byte_tab[(int) (unsigned char) rbuf[rp++]] << hibit);
|
||||
hibit += 8;
|
||||
|
||||
if (rp >= rs) /* buffer underrun */
|
||||
{
|
||||
rs = read (fd, rbuf, sizeof (rbuf));
|
||||
|
||||
if (rs < 0)
|
||||
{ perror ("read4");
|
||||
break;
|
||||
}
|
||||
|
||||
rr += rs;
|
||||
pika_progress_update ((float) rr / rsize / 2.0);
|
||||
rp = 0;
|
||||
if (rs == 0)
|
||||
goto do_write;
|
||||
}
|
||||
}
|
||||
}
|
||||
nr_pels = -1; /* handle as if eol */
|
||||
}
|
||||
else /* p != NULL <-> valid code */
|
||||
{
|
||||
data >>= p->nr_bits;
|
||||
hibit -= p->nr_bits;
|
||||
|
||||
nr_pels = ((struct g3_leaf *) p)->nr_pels;
|
||||
#ifdef DEBUG
|
||||
g_printerr ("PELs: %d (%c)\n", nr_pels, '0' + color);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* handle EOL (including fill bits) */
|
||||
if (nr_pels == -1)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
g_printerr ("hibit=%2d, data=", hibit);
|
||||
putbin (data);
|
||||
#endif
|
||||
/* skip filler 0bits -> seek for "1"-bit */
|
||||
while ((data & 0x01) != 1)
|
||||
{
|
||||
if ((data & 0xf) == 0) /* nibble optimization */
|
||||
{
|
||||
hibit-= 4;
|
||||
data >>= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
hibit--;
|
||||
data >>= 1;
|
||||
}
|
||||
|
||||
/* fill higher bits */
|
||||
if (hibit < 20)
|
||||
{
|
||||
data |= ( byte_tab[(int) (unsigned char) rbuf[ rp++]] << hibit);
|
||||
hibit += 8;
|
||||
|
||||
if (rp >= rs) /* buffer underrun */
|
||||
{
|
||||
rs = read (fd, rbuf, sizeof (rbuf));
|
||||
if ( rs < 0 )
|
||||
{
|
||||
perror ("read3");
|
||||
break;
|
||||
}
|
||||
rr += rs;
|
||||
pika_progress_update ((float) rr / rsize / 2.0);
|
||||
rp = 0;
|
||||
if (rs == 0)
|
||||
goto do_write;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
g_printerr ("hibit=%2d, data=", hibit );
|
||||
putbin(data);
|
||||
#endif
|
||||
} /* end skip 0bits */
|
||||
hibit--;
|
||||
data >>=1;
|
||||
|
||||
color = 0;
|
||||
|
||||
if (col == 0)
|
||||
{
|
||||
if (last_eol_row != row)
|
||||
{
|
||||
cons_eol++; /* consecutive EOLs */
|
||||
last_eol_row = row;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (col > hcol && col <= MAX_COLS)
|
||||
hcol = col;
|
||||
row++;
|
||||
|
||||
/* bitmap memory full? make it larger! */
|
||||
if (row >= max_rows)
|
||||
{
|
||||
gchar *p = g_try_realloc (bitmap,
|
||||
(max_rows += 500) * MAX_COLS / 8);
|
||||
if (p == NULL)
|
||||
{
|
||||
perror ("realloc() failed, page truncated");
|
||||
rs = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bitmap = p;
|
||||
memset (&bitmap[ row * MAX_COLS / 8 ], 0,
|
||||
(max_rows - row) * MAX_COLS / 8);
|
||||
}
|
||||
}
|
||||
|
||||
col=0; bp = &bitmap[row * MAX_COLS / 8];
|
||||
cons_eol = 0;
|
||||
}
|
||||
}
|
||||
else /* not eol */
|
||||
{
|
||||
if (col + nr_pels > MAX_COLS)
|
||||
nr_pels = MAX_COLS - col;
|
||||
|
||||
if (color == 0) /* white */
|
||||
{
|
||||
col += nr_pels;
|
||||
}
|
||||
else /* black */
|
||||
{
|
||||
register int bit = (0x80 >> (col & 07));
|
||||
register char *w = & bp[col >> 3];
|
||||
|
||||
for (i = nr_pels; i > 0; i--)
|
||||
{
|
||||
*w |= bit;
|
||||
bit >>=1;
|
||||
if (bit == 0)
|
||||
{
|
||||
bit = 0x80;
|
||||
w++;
|
||||
}
|
||||
col++;
|
||||
}
|
||||
}
|
||||
|
||||
if (nr_pels < 64)
|
||||
color = !color; /* terminating code */
|
||||
}
|
||||
} /* end main loop */
|
||||
|
||||
do_write: /* write pbm (or whatever) file */
|
||||
|
||||
if (fd != 0)
|
||||
close (fd); /* close input file */
|
||||
|
||||
#ifdef DEBUG
|
||||
g_printerr ("consecutive EOLs: %d, max columns: %d\n", cons_eol, hcol);
|
||||
#endif
|
||||
|
||||
image = emitpika (hcol, row, bitmap, bperrow, file, error);
|
||||
|
||||
g_free (bitmap);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/* hcol is the number of columns, row the number of rows
|
||||
* bperrow is the number of bytes actually used by hcol, which may
|
||||
* be greater than (hcol+7)/8 [in case of an unscaled g3 image less
|
||||
* than 1728 pixels wide]
|
||||
*/
|
||||
|
||||
static PikaImage *
|
||||
emitpika (gint hcol,
|
||||
gint row,
|
||||
const gchar *bitmap,
|
||||
gint bperrow,
|
||||
GFile *file,
|
||||
GError **error)
|
||||
{
|
||||
GeglBuffer *buffer;
|
||||
PikaImage *image;
|
||||
PikaLayer *layer;
|
||||
guchar *buf;
|
||||
guchar tmp;
|
||||
gint x, y;
|
||||
gint xx, yy;
|
||||
gint tile_height;
|
||||
|
||||
/* initialize */
|
||||
|
||||
tmp = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
g_printerr ("emit pika: %d x %d\n", hcol, row);
|
||||
#endif
|
||||
|
||||
if (hcol > PIKA_MAX_IMAGE_SIZE || hcol <= 0 ||
|
||||
row > PIKA_MAX_IMAGE_SIZE || row <= 0)
|
||||
{
|
||||
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||
_("Invalid image dimensions (%d x %d). "
|
||||
"Image may be corrupt."),
|
||||
hcol, row);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
image = pika_image_new (hcol, row, PIKA_GRAY);
|
||||
if (! image)
|
||||
{
|
||||
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||
_("Could not create image."));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
layer = pika_layer_new (image, _("Background"),
|
||||
hcol,
|
||||
row,
|
||||
PIKA_GRAY_IMAGE,
|
||||
100,
|
||||
pika_image_get_default_new_layer_mode (image));
|
||||
pika_image_insert_layer (image, layer, NULL, 0);
|
||||
|
||||
buffer = pika_drawable_get_buffer (PIKA_DRAWABLE (layer));
|
||||
|
||||
tile_height = pika_tile_height ();
|
||||
#ifdef DEBUG
|
||||
g_printerr ("tile height: %d\n", tile_height);
|
||||
#endif
|
||||
|
||||
buf = g_new (guchar, hcol * tile_height);
|
||||
if (! buf)
|
||||
{
|
||||
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||
_("Could not create buffer to process image data."));
|
||||
g_object_unref (buffer);
|
||||
pika_image_delete(image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xx = 0;
|
||||
yy = 0;
|
||||
|
||||
for (y = 0; y < row; y++)
|
||||
{
|
||||
for (x = 0; x < hcol; x++)
|
||||
{
|
||||
if ((x & 7) == 0)
|
||||
tmp = bitmap[y * bperrow + (x >> 3)];
|
||||
|
||||
buf[xx++] = tmp&(128 >> (x & 7)) ? 0 : 255;
|
||||
}
|
||||
|
||||
if ((y - yy) == tile_height - 1)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
g_printerr ("update tile height: %d\n", tile_height);
|
||||
#endif
|
||||
|
||||
gegl_buffer_set (buffer, GEGL_RECTANGLE (0, yy, hcol, tile_height), 0,
|
||||
NULL, buf, GEGL_AUTO_ROWSTRIDE);
|
||||
|
||||
pika_progress_update (0.5 + (float) y / row / 2.0);
|
||||
|
||||
xx = 0;
|
||||
yy += tile_height;
|
||||
}
|
||||
}
|
||||
|
||||
if (row - yy)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
g_printerr ("update rest: %d\n", row-yy);
|
||||
#endif
|
||||
|
||||
gegl_buffer_set (buffer, GEGL_RECTANGLE (0, yy, hcol, row - yy), 0,
|
||||
NULL, buf, GEGL_AUTO_ROWSTRIDE);
|
||||
}
|
||||
|
||||
pika_progress_update (1.0);
|
||||
|
||||
g_free (buf);
|
||||
|
||||
g_object_unref (buffer);
|
||||
|
||||
return image;
|
||||
}
|
277
plug-ins/file-faxg3/g3.c
Normal file
277
plug-ins/file-faxg3/g3.c
Normal file
@ -0,0 +1,277 @@
|
||||
/* #ident "@(#)g3.c 3.1 95/08/30 Copyright (c) Gert Doering" */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "g3.h"
|
||||
|
||||
struct g3code t_white[66] = {
|
||||
{ 0, 0, 0x0ac, 8 },
|
||||
{ 0, 1, 0x038, 6 },
|
||||
{ 0, 2, 0x00e, 4 },
|
||||
{ 0, 3, 0x001, 4 },
|
||||
{ 0, 4, 0x00d, 4 },
|
||||
{ 0, 5, 0x003, 4 },
|
||||
{ 0, 6, 0x007, 4 },
|
||||
{ 0, 7, 0x00f, 4 },
|
||||
{ 0, 8, 0x019, 5 },
|
||||
{ 0, 9, 0x005, 5 },
|
||||
{ 0, 10, 0x01c, 5 },
|
||||
{ 0, 11, 0x002, 5 },
|
||||
{ 0, 12, 0x004, 6 },
|
||||
{ 0, 13, 0x030, 6 },
|
||||
{ 0, 14, 0x00b, 6 },
|
||||
{ 0, 15, 0x02b, 6 },
|
||||
{ 0, 16, 0x015, 6 },
|
||||
{ 0, 17, 0x035, 6 },
|
||||
{ 0, 18, 0x072, 7 },
|
||||
{ 0, 19, 0x018, 7 },
|
||||
{ 0, 20, 0x008, 7 },
|
||||
{ 0, 21, 0x074, 7 },
|
||||
{ 0, 22, 0x060, 7 },
|
||||
{ 0, 23, 0x010, 7 },
|
||||
{ 0, 24, 0x00a, 7 },
|
||||
{ 0, 25, 0x06a, 7 },
|
||||
{ 0, 26, 0x064, 7 },
|
||||
{ 0, 27, 0x012, 7 },
|
||||
{ 0, 28, 0x00c, 7 },
|
||||
{ 0, 29, 0x040, 8 },
|
||||
{ 0, 30, 0x0c0, 8 },
|
||||
{ 0, 31, 0x058, 8 },
|
||||
{ 0, 32, 0x0d8, 8 },
|
||||
{ 0, 33, 0x048, 8 },
|
||||
{ 0, 34, 0x0c8, 8 },
|
||||
{ 0, 35, 0x028, 8 },
|
||||
{ 0, 36, 0x0a8, 8 },
|
||||
{ 0, 37, 0x068, 8 },
|
||||
{ 0, 38, 0x0e8, 8 },
|
||||
{ 0, 39, 0x014, 8 },
|
||||
{ 0, 40, 0x094, 8 },
|
||||
{ 0, 41, 0x054, 8 },
|
||||
{ 0, 42, 0x0d4, 8 },
|
||||
{ 0, 43, 0x034, 8 },
|
||||
{ 0, 44, 0x0b4, 8 },
|
||||
{ 0, 45, 0x020, 8 },
|
||||
{ 0, 46, 0x0a0, 8 },
|
||||
{ 0, 47, 0x050, 8 },
|
||||
{ 0, 48, 0x0d0, 8 },
|
||||
{ 0, 49, 0x04a, 8 },
|
||||
{ 0, 50, 0x0ca, 8 },
|
||||
{ 0, 51, 0x02a, 8 },
|
||||
{ 0, 52, 0x0aa, 8 },
|
||||
{ 0, 53, 0x024, 8 },
|
||||
{ 0, 54, 0x0a4, 8 },
|
||||
{ 0, 55, 0x01a, 8 },
|
||||
{ 0, 56, 0x09a, 8 },
|
||||
{ 0, 57, 0x05a, 8 },
|
||||
{ 0, 58, 0x0da, 8 },
|
||||
{ 0, 59, 0x052, 8 },
|
||||
{ 0, 60, 0x0d2, 8 },
|
||||
{ 0, 61, 0x04c, 8 },
|
||||
{ 0, 62, 0x0cc, 8 },
|
||||
{ 0, 63, 0x02c, 8 },
|
||||
{ 0, -1, 0, 11 }, /* 11 0-bits == EOL, special handling */
|
||||
{ 0, -1, 0, 0 }}; /* end of table */
|
||||
|
||||
/* make-up codes white */
|
||||
struct g3code m_white[28] = {
|
||||
{ 0, 64, 0x01b, 5 },
|
||||
{ 0, 128, 0x009, 5 },
|
||||
{ 0, 192, 0x03a, 6 },
|
||||
{ 0, 256, 0x076, 7 },
|
||||
{ 0, 320, 0x06c, 8 },
|
||||
{ 0, 384, 0x0ec, 8 },
|
||||
{ 0, 448, 0x026, 8 },
|
||||
{ 0, 512, 0x0a6, 8 },
|
||||
{ 0, 576, 0x016, 8 },
|
||||
{ 0, 640, 0x0e6, 8 },
|
||||
{ 0, 704, 0x066, 9 },
|
||||
{ 0, 768, 0x166, 9 },
|
||||
{ 0, 832, 0x096, 9 },
|
||||
{ 0, 896, 0x196, 9 },
|
||||
{ 0, 960, 0x056, 9 },
|
||||
{ 0,1024, 0x156, 9 },
|
||||
{ 0,1088, 0x0d6, 9 },
|
||||
{ 0,1152, 0x1d6, 9 },
|
||||
{ 0,1216, 0x036, 9 },
|
||||
{ 0,1280, 0x136, 9 },
|
||||
{ 0,1344, 0x0b6, 9 },
|
||||
{ 0,1408, 0x1b6, 9 },
|
||||
{ 0,1472, 0x032, 9 },
|
||||
{ 0,1536, 0x132, 9 },
|
||||
{ 0,1600, 0x0b2, 9 },
|
||||
{ 0,1664, 0x006, 6 },
|
||||
{ 0,1728, 0x1b2, 9 },
|
||||
{ 0, -1, 0, 0} };
|
||||
|
||||
|
||||
struct g3code t_black[66] = {
|
||||
{ 0, 0, 0x3b0, 10 },
|
||||
{ 0, 1, 0x002, 3 },
|
||||
{ 0, 2, 0x003, 2 },
|
||||
{ 0, 3, 0x001, 2 },
|
||||
{ 0, 4, 0x006, 3 },
|
||||
{ 0, 5, 0x00c, 4 },
|
||||
{ 0, 6, 0x004, 4 },
|
||||
{ 0, 7, 0x018, 5 },
|
||||
{ 0, 8, 0x028, 6 },
|
||||
{ 0, 9, 0x008, 6 },
|
||||
{ 0, 10, 0x010, 7 },
|
||||
{ 0, 11, 0x050, 7 },
|
||||
{ 0, 12, 0x070, 7 },
|
||||
{ 0, 13, 0x020, 8 },
|
||||
{ 0, 14, 0x0e0, 8 },
|
||||
{ 0, 15, 0x030, 9 },
|
||||
{ 0, 16, 0x3a0, 10 },
|
||||
{ 0, 17, 0x060, 10 },
|
||||
{ 0, 18, 0x040, 10 },
|
||||
{ 0, 19, 0x730, 11 },
|
||||
{ 0, 20, 0x0b0, 11 },
|
||||
{ 0, 21, 0x1b0, 11 },
|
||||
{ 0, 22, 0x760, 11 },
|
||||
{ 0, 23, 0x0a0, 11 },
|
||||
{ 0, 24, 0x740, 11 },
|
||||
{ 0, 25, 0x0c0, 11 },
|
||||
{ 0, 26, 0x530, 12 },
|
||||
{ 0, 27, 0xd30, 12 },
|
||||
{ 0, 28, 0x330, 12 },
|
||||
{ 0, 29, 0xb30, 12 },
|
||||
{ 0, 30, 0x160, 12 },
|
||||
{ 0, 31, 0x960, 12 },
|
||||
{ 0, 32, 0x560, 12 },
|
||||
{ 0, 33, 0xd60, 12 },
|
||||
{ 0, 34, 0x4b0, 12 },
|
||||
{ 0, 35, 0xcb0, 12 },
|
||||
{ 0, 36, 0x2b0, 12 },
|
||||
{ 0, 37, 0xab0, 12 },
|
||||
{ 0, 38, 0x6b0, 12 },
|
||||
{ 0, 39, 0xeb0, 12 },
|
||||
{ 0, 40, 0x360, 12 },
|
||||
{ 0, 41, 0xb60, 12 },
|
||||
{ 0, 42, 0x5b0, 12 },
|
||||
{ 0, 43, 0xdb0, 12 },
|
||||
{ 0, 44, 0x2a0, 12 },
|
||||
{ 0, 45, 0xaa0, 12 },
|
||||
{ 0, 46, 0x6a0, 12 },
|
||||
{ 0, 47, 0xea0, 12 },
|
||||
{ 0, 48, 0x260, 12 },
|
||||
{ 0, 49, 0xa60, 12 },
|
||||
{ 0, 50, 0x4a0, 12 },
|
||||
{ 0, 51, 0xca0, 12 },
|
||||
{ 0, 52, 0x240, 12 },
|
||||
{ 0, 53, 0xec0, 12 },
|
||||
{ 0, 54, 0x1c0, 12 },
|
||||
{ 0, 55, 0xe40, 12 },
|
||||
{ 0, 56, 0x140, 12 },
|
||||
{ 0, 57, 0x1a0, 12 },
|
||||
{ 0, 58, 0x9a0, 12 },
|
||||
{ 0, 59, 0xd40, 12 },
|
||||
{ 0, 60, 0x340, 12 },
|
||||
{ 0, 61, 0x5a0, 12 },
|
||||
{ 0, 62, 0x660, 12 },
|
||||
{ 0, 63, 0xe60, 12 },
|
||||
{ 0, -1, 0x000, 11 },
|
||||
{ 0, -1, 0, 0 } };
|
||||
|
||||
struct g3code m_black[28] = {
|
||||
{ 0, 64, 0x3c0, 10 },
|
||||
{ 0, 128, 0x130, 12 },
|
||||
{ 0, 192, 0x930, 12 },
|
||||
{ 0, 256, 0xda0, 12 },
|
||||
{ 0, 320, 0xcc0, 12 },
|
||||
{ 0, 384, 0x2c0, 12 },
|
||||
{ 0, 448, 0xac0, 12 },
|
||||
{ 0, 512, 0x6c0, 13 },
|
||||
{ 0, 576,0x16c0, 13 },
|
||||
{ 0, 640, 0xa40, 13 },
|
||||
{ 0, 704,0x1a40, 13 },
|
||||
{ 0, 768, 0x640, 13 },
|
||||
{ 0, 832,0x1640, 13 },
|
||||
{ 0, 896, 0x9c0, 13 },
|
||||
{ 0, 960,0x19c0, 13 },
|
||||
{ 0,1024, 0x5c0, 13 },
|
||||
{ 0,1088,0x15c0, 13 },
|
||||
{ 0,1152, 0xdc0, 13 },
|
||||
{ 0,1216,0x1dc0, 13 },
|
||||
{ 0,1280, 0x940, 13 },
|
||||
{ 0,1344,0x1940, 13 },
|
||||
{ 0,1408, 0x540, 13 },
|
||||
{ 0,1472,0x1540, 13 },
|
||||
{ 0,1536, 0xb40, 13 },
|
||||
{ 0,1600,0x1b40, 13 },
|
||||
{ 0,1664, 0x4c0, 13 },
|
||||
{ 0,1728,0x14c0, 13 },
|
||||
{ 0, -1, 0, 0 } };
|
||||
|
||||
void tree_add_node( struct g3_tree *p, struct g3code * g3c,
|
||||
int bit_code, int bit_length )
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( bit_length <= FBITS ) /* leaf (multiple bits) */
|
||||
{
|
||||
g3c->nr_bits = bit_length; /* leaf tag */
|
||||
|
||||
if ( bit_length == FBITS ) /* full width */
|
||||
{
|
||||
p->nextb[ bit_code ] = (struct g3_tree *) g3c;
|
||||
}
|
||||
else /* fill bits */
|
||||
for ( i=0; i< ( 1 << (FBITS-bit_length)); i++ )
|
||||
{
|
||||
p->nextb[ bit_code + ( i << bit_length ) ] = (struct g3_tree *) g3c;
|
||||
}
|
||||
}
|
||||
else /* node */
|
||||
{
|
||||
struct g3_tree *p2;
|
||||
|
||||
p2 = p->nextb[ bit_code & BITM ];
|
||||
if ( p2 == 0 ) /* no sub-node exists */
|
||||
{
|
||||
p2 = p->nextb[ bit_code & BITM ] =
|
||||
( struct g3_tree * ) calloc( 1, sizeof( struct g3_tree ));
|
||||
if ( p2 == NULL ) { perror( "malloc 3" ); exit(11); }
|
||||
p2->nr_bits = 0; /* node tag */
|
||||
|
||||
}
|
||||
if ( p2->nr_bits != 0 )
|
||||
{
|
||||
g_printerr ("internal table setup error\n" ); exit(6);
|
||||
}
|
||||
tree_add_node( p2, g3c, bit_code >> FBITS, bit_length - FBITS );
|
||||
}
|
||||
}
|
||||
|
||||
void build_tree (struct g3_tree ** p, struct g3code * c )
|
||||
{
|
||||
if ( *p == NULL )
|
||||
{
|
||||
(*p) = (struct g3_tree *) calloc( 1, sizeof(struct g3_tree) );
|
||||
if ( *p == NULL ) { perror( "malloc(1)" ); exit(10); }
|
||||
|
||||
(*p)->nr_bits=0;
|
||||
}
|
||||
|
||||
while ( c->bit_length != 0 )
|
||||
{
|
||||
tree_add_node( *p, c, c->bit_code, c->bit_length );
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
void init_byte_tab (int reverse, int byte_tab[] )
|
||||
{
|
||||
int i;
|
||||
if ( reverse ) for ( i=0; i<256; i++ ) byte_tab[i] = i;
|
||||
else
|
||||
for ( i=0; i<256; i++ )
|
||||
byte_tab[i] = ( ((i & 0x01) << 7) | ((i & 0x02) << 5) |
|
||||
((i & 0x04) << 3) | ((i & 0x08) << 1) |
|
||||
((i & 0x10) >> 1) | ((i & 0x20) >> 3) |
|
||||
((i & 0x40) >> 5) | ((i & 0x80) >> 7) );
|
||||
}
|
55
plug-ins/file-faxg3/g3.h
Normal file
55
plug-ins/file-faxg3/g3.h
Normal file
@ -0,0 +1,55 @@
|
||||
/* #ident "@(#)g3.h 3.1 95/08/30 Copyright (c) Gert Doering" */
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0L
|
||||
#endif
|
||||
|
||||
/* nr_bits is set to ( bit_length MOD FBITS ) by build_g3_tree,
|
||||
* nr_pels is the number of pixels to write for that code,
|
||||
* bit_code is the code itself (msb2lsb), and bit_length its length
|
||||
*/
|
||||
|
||||
struct g3code { int nr_bits, nr_pels, bit_code, bit_length; };
|
||||
|
||||
/* tables for makeup / terminal codes white / black, extended m_codes */
|
||||
extern struct g3code t_white[], m_white[], t_black[], m_black[], m_ext[];
|
||||
|
||||
/* The number of bits looked up simultaneously determines the amount
|
||||
* of memory used by the program - some values:
|
||||
* 10 bits : 87 Kbytes, 8 bits : 20 Kbytes
|
||||
* 5 bits : 6 Kbytes, 1 bit : 4 Kbytes
|
||||
* - naturally, using less bits is also slower...
|
||||
*/
|
||||
|
||||
/*
|
||||
#define FBITS 5
|
||||
#define BITM 0x1f
|
||||
*/
|
||||
|
||||
#define FBITS 8
|
||||
#define BITM 0xff
|
||||
|
||||
/*
|
||||
#define FBITS 12
|
||||
#define BITM 0xfff
|
||||
*/
|
||||
|
||||
#define BITN 1<<FBITS
|
||||
|
||||
struct g3_tree { int nr_bits;
|
||||
struct g3_tree * nextb[ BITN ];
|
||||
};
|
||||
|
||||
#define g3_leaf g3code
|
||||
|
||||
extern void tree_add_node ( struct g3_tree *p, struct g3code * g3c,
|
||||
int bit_code, int bit_length );
|
||||
extern void build_tree ( struct g3_tree ** p, struct g3code * c );
|
||||
|
||||
#ifdef DEBUG
|
||||
extern void print_g3_tree ( char * t, struct g3_tree * p );
|
||||
#endif
|
||||
|
||||
extern void init_byte_tab ( int reverse, int byte_tab[] );
|
||||
|
||||
|
27
plug-ins/file-faxg3/meson.build
Normal file
27
plug-ins/file-faxg3/meson.build
Normal file
@ -0,0 +1,27 @@
|
||||
plugin_name = 'file-faxg3'
|
||||
|
||||
plugin_sources = [
|
||||
'faxg3.c',
|
||||
'g3.c',
|
||||
]
|
||||
|
||||
if platform_windows
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
'--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
'--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
'--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
],
|
||||
)
|
||||
endif
|
||||
|
||||
executable(plugin_name,
|
||||
plugin_sources,
|
||||
dependencies: libpikaui_dep,
|
||||
install: true,
|
||||
install_dir: pikaplugindir / 'plug-ins' / plugin_name,
|
||||
)
|
Reference in New Issue
Block a user