home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2002 June
/
Chip_2002-06_cd1.bin
/
ctenari
/
Krutak
/
univiewi_jbig.exe
/
plugins
/
JBIG
/
src
/
jbig.cpp
next >
Wrap
C/C++ Source or Header
|
2002-03-10
|
10KB
|
392 lines
/*
UniView JBIG I/O plugin
Copyright (C) 2001-2002 Andrej Krutak
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 2 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <windows.h>
#include <stdio.h>
#include "cimage.h"
#include "plugin.h"
extern "C" {
#include <jbig.h>
}
int MsgBox(UINT fuStyle, char *pszFormat, ...)
{
va_list va;
char msgMessage[2048];
int n;
va_start(va, pszFormat);
vsprintf(msgMessage, pszFormat, va);
va_end(va);
n = MessageBox(GetFocus(), msgMessage, "JBIG-filter", fuStyle|MB_SETFOREGROUND|MB_APPLMODAL);
return n;
}
int open_jbig_cursor;
const int open_jbig_bufsize=8192;
void open_jbig_collect_image(unsigned char *data, size_t len, void *image)
{
int i;
for (i = 0; (unsigned)i < len; i++) {
((unsigned char *)image)[open_jbig_cursor++] = data[i];
}
}
int open_jbig_write_pnm (CImage *img, const unsigned char * const image, const int bpp, const int rows, const int cols, const int maxval, const int format)
{
int row;
int col;
int j;
if (UVImage_recreate(img, cols, rows, bpp*8)) {
if (cols<=0||rows<=0)
return UNSUP_FORMAT;
return OUT_OF_MEMORY;
}
for (row = 0; row < rows; row++) {
for (col = 0; col < cols; col++) {
for (j = 0; j < bpp; j++)
UVImage_setGR(img, col, row, image[(((row*cols)+col) * bpp) + j]);
}
}
return 0;
}
int open_jbig_write_raw_pbm(CImage *img, const unsigned char * const binary_image, const int rows, const int cols)
{
int byte;
int bit;
int row;
if (UVImage_recreate(img, cols, rows, 1)) {
if (cols<=0||rows<=0)
return UNSUP_FORMAT;
return OUT_OF_MEMORY;
}
for (row = 0; row < rows; row++) {
const int bytes_per_row = (cols + 7) / 8;
for (byte = 0; byte < bytes_per_row; byte++) {
for (bit = 0; bit < 8; bit++) {
int col = byte*8 + bit;
if (col < cols)
UVImage_setGR(img, col, row, binary_image[row*bytes_per_row+byte] & 1 << (8-bit-1) ? 0 : 255);
}
}
}
return 0;
}
int pm_bitstomaxval(int const bits)
{
return ( 1 << bits ) - 1;
}
int __stdcall _open_jbig(CImage &timg, char *path, int showerrdetails)
{
FILE *fin;
int result;
int all_args = 0, files = 0;
struct jbg_dec_state s;
char *buffer;
unsigned char *p;
size_t len, cnt;
unsigned long xmax = 4294967295UL, ymax = 4294967295UL;
int plane = -1, use_graycode = 1, diagnose = 0;
int rv=0;
CImage *img=&timg;
open_jbig_cursor=0;
buffer = (char*)malloc(open_jbig_bufsize);
if (!buffer) {
return OUT_OF_MEMORY;
}
fin=fopen(path, "rb");
if (fin==NULL) {
free(buffer);
return FILE_ERROR;
}
//send input file to decoder
jbg_dec_init(&s);
jbg_dec_maxsize(&s, xmax, ymax);
result = JBG_EAGAIN;
do {
len = fread(buffer, 1, open_jbig_bufsize, fin);
if (!len) break;
cnt = 0;
p = (unsigned char *) buffer;
while (len > 0 && (result == JBG_EAGAIN || result == JBG_EOK)) {
result = jbg_dec_in(&s, p, len, &cnt);
p += cnt;
len -= cnt;
}
} while (result == JBG_EAGAIN || result == JBG_EOK);
if (ferror(fin)) {
if (showerrdetails) MsgBox(MB_OK|MB_ICONSTOP, "Problem while reading input file '%s", path);
fclose(fin);
free(buffer);
return UNSUP_FORMAT;
}
if (result != JBG_EOK && result != JBG_EOK_INTR) {
if (showerrdetails) MsgBox(MB_OK|MB_ICONSTOP, "Problem with input file '%s': %s\n", path, jbg_strerror(result, JBG_EN));
fclose(fin);
free(buffer);
return UNSUP_FORMAT;
}
if (plane >= 0 && jbg_dec_getplanes(&s) <= plane) {
if (showerrdetails) MsgBox(MB_OK|MB_ICONSTOP, "Image has only %d planes!\n", jbg_dec_getplanes(&s));
fclose(fin);
free(buffer);
return UNSUP_FORMAT;
}
{
//Write it out
int rows, cols;
int maxval;
int bpp;
int plane_to_write;
cols = jbg_dec_getwidth(&s);
rows = jbg_dec_getheight(&s);
maxval = pm_bitstomaxval(jbg_dec_getplanes(&s));
bpp = (jbg_dec_getplanes(&s)+7)/8;
if (jbg_dec_getplanes(&s) == 1)
plane_to_write = 0;
else
plane_to_write = plane;
if (plane_to_write >= 0) {
BYTE* binary_image;
binary_image=jbg_dec_getimage(&s, plane_to_write);
rv=open_jbig_write_raw_pbm(img, binary_image, rows, cols);
} else {
BYTE* image;
image = (BYTE*)malloc(cols*rows*bpp);
jbg_dec_merge_planes(&s, use_graycode, open_jbig_collect_image, image);
rv=open_jbig_write_pnm(img, image, bpp, rows, cols, maxval, 1);
free(image);
}
}
fclose(fin);
free(buffer);
jbg_dec_free(&s);
return rv;
}
void save_jbig_data_out(unsigned char *start, size_t len, void *file)
{
fwrite(start, len, 1, (FILE *) file);
}
int pm_maxvaltobits(int const maxval)
{
if ( maxval <= 1 )
return 1;
else if ( maxval <= 3 )
return 2;
else if ( maxval <= 7 )
return 3;
else if ( maxval <= 15 )
return 4;
else if ( maxval <= 31 )
return 5;
else if ( maxval <= 63 )
return 6;
else if ( maxval <= 127 )
return 7;
else if ( maxval <= 255 )
return 8;
else if ( maxval <= 511 )
return 9;
else if ( maxval <= 1023 )
return 10;
else if ( maxval <= 2047 )
return 11;
else if ( maxval <= 4095 )
return 12;
else if ( maxval <= 8191 )
return 13;
else if ( maxval <= 16383 )
return 14;
else if ( maxval <= 32767 )
return 15;
else if ( (long) maxval <= 65535L )
return 16;
else
return -1;
}
int __stdcall _save_jbig(CImage &timg, char *path, int grey)
{
FILE *fout;
int all_args = 0, files = 0;
int bpp, planes, encode_planes = -1;
int cols, rows;
int bytes_per_line;
unsigned char **bitmap;
unsigned char *image;
struct jbg_enc_state s;
int verbose = 0, delay_at = 0, use_graycode = 1;
long mwidth = 640, mheight = 480;
int dl = -1, dh = -1, d = -1, l0 = -1, mx = -1;
int options = JBG_TPDON | JBG_TPBON | JBG_DPON;
int order = JBG_ILEAVE | JBG_SMID;
CImage *img=&timg;
fout=fopen(path, "wb");
if (fout==NULL)
return FILE_ERROR;
if (!grey)
use_graycode = 0;
cols=UVImage_getXSize(img);
rows=UVImage_getYSize(img);
UVImage_colortable_make(img);
if (!UVImage_colortable_isblackwhite(img)) {
if (grey&&!UVImage_colortable_isgreyscale(img))
UVImage_effect_makegray_light(img);
else if (!grey)
UVImage_quantize(img, 2, 5);
}
UVImage_colortable_free(img);
planes=pm_maxvaltobits(UVImage_getBPP(img)==1?1:255);
bpp = (planes + 7) / 8;
if (encode_planes < 0 || encode_planes > planes)
encode_planes = planes;
bytes_per_line = (cols + 7) / 8;
image = (BYTE*)malloc(cols * rows * bpp);
if (image==NULL) {
fclose(fout);
return OUT_OF_MEMORY;
}
int row;
for (row = 0; row < rows; row++) {
int col;
for (col = 0; col < cols; col++) {
int j;
for (j = 0; j < bpp; j++)
image[(((row*cols)+col) * bpp) + j]=UVImage_getL(img, col, row) >> ((bpp-1-j) * 8);
}
}
int i;
bitmap = (unsigned char **) malloc(sizeof(unsigned char *) * encode_planes);
if (bitmap==NULL) {
free(image);
fclose(fout);
return OUT_OF_MEMORY;
}
for (i = 0; i < encode_planes; i++) {
bitmap[i] = (unsigned char *) malloc(bytes_per_line * rows);
if (bitmap[i]==NULL) {
int j;
for (j=0; j<i; j++)
free(bitmap[i]);
free(bitmap);
free(image);
fclose(fout);
return OUT_OF_MEMORY;
}
}
jbg_split_planes(cols, rows, planes, encode_planes, image, bitmap, use_graycode);
free(image);
if (encode_planes == 1) {
int row;
for (row = 0; row < rows; row++) {
int i;
for (i = 0; i < bytes_per_line; i++)
bitmap[0][(row*bytes_per_line) + i] ^= 0xff;
}
}
jbg_enc_init(&s, cols, rows, encode_planes, bitmap, save_jbig_data_out, fout);
if (d >= 0)
jbg_enc_layers(&s, d);
else
jbg_enc_lrlmax(&s, mwidth, mheight);
if (delay_at)
options |= JBG_DELAY_AT;
jbg_enc_lrange(&s, dl, dh);
jbg_enc_options(&s, order, options, l0, mx, -1);
jbg_enc_out(&s);
jbg_enc_free(&s);
for (i=0; i<encode_planes; i++)
free(bitmap[i]);
free(bitmap);
fclose(fout);
return 0;
}
int uvplugin_init(up_initdata* updata)
{
updata->items_count=0;
strcpy(updata->plugin_name, "JBIG import/export filter (us)");
updata->version_1=1;
updata->version_2=8;
return 0;
}
int __stdcall uvplugin_main(HINSTANCE plgI, DWORD message, DWORD wParam, DWORD lParam)
{
switch (message) {
case UVMSG_INITPLUGIN:
return uvplugin_init((up_initdata*)wParam);
case UVMSG_EXIT:
return 0;
case UVMSG_STOPEXIT:
return 0;
}
return 0;
}