home *** CD-ROM | disk | FTP | other *** search
Wrap
/* 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; }