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 >
C/C++ Source or Header  |  2002-03-10  |  10KB  |  392 lines

  1. /*
  2.     UniView JBIG I/O plugin
  3.     Copyright (C) 2001-2002 Andrej Krutak
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  18. */
  19.  
  20. #include <windows.h>
  21. #include <stdio.h>
  22. #include "cimage.h"
  23. #include "plugin.h"
  24.  
  25. extern "C" {
  26.     #include <jbig.h>
  27. }
  28.  
  29. int MsgBox(UINT fuStyle, char *pszFormat, ...)
  30. {
  31.     va_list     va;
  32.     char        msgMessage[2048];
  33.     int         n;
  34.  
  35.     va_start(va, pszFormat);
  36.     vsprintf(msgMessage, pszFormat, va);
  37.     va_end(va);
  38.  
  39.     n = MessageBox(GetFocus(), msgMessage, "JBIG-filter", fuStyle|MB_SETFOREGROUND|MB_APPLMODAL);
  40.  
  41.     return n;
  42. }
  43.  
  44. int open_jbig_cursor;
  45. const int open_jbig_bufsize=8192;
  46.  
  47. void open_jbig_collect_image(unsigned char *data, size_t len, void *image)
  48. {
  49.     int i;
  50.  
  51.     for (i = 0; (unsigned)i < len; i++) {
  52.         ((unsigned char *)image)[open_jbig_cursor++] = data[i];
  53.     }
  54. }
  55.  
  56. 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)
  57. {
  58.     int row;
  59.     int col;
  60.     int j;
  61.  
  62.     if (UVImage_recreate(img, cols, rows, bpp*8)) {
  63.         if (cols<=0||rows<=0)
  64.             return UNSUP_FORMAT;
  65.         return OUT_OF_MEMORY;
  66.     }
  67.  
  68.     for (row = 0; row < rows; row++) {
  69.         for (col = 0; col < cols; col++) {
  70.             for (j = 0; j < bpp; j++)
  71.                 UVImage_setGR(img, col, row, image[(((row*cols)+col) * bpp) + j]);
  72.         }
  73.     }
  74.     return 0;
  75. }
  76.  
  77.  
  78. int open_jbig_write_raw_pbm(CImage *img, const unsigned char * const binary_image, const int rows, const int cols)
  79. {
  80.     int byte;
  81.     int bit;
  82.     int row;
  83.  
  84.     if (UVImage_recreate(img, cols, rows, 1)) {
  85.         if (cols<=0||rows<=0)
  86.             return UNSUP_FORMAT;
  87.         return OUT_OF_MEMORY;
  88.     }
  89.  
  90.     for (row = 0; row < rows; row++) {
  91.         const int bytes_per_row = (cols + 7) / 8;
  92.         for (byte = 0; byte < bytes_per_row; byte++) {
  93.             for (bit = 0; bit < 8; bit++) {
  94.                 int col = byte*8 + bit;
  95.                 if (col < cols)
  96.                     UVImage_setGR(img, col, row, binary_image[row*bytes_per_row+byte] & 1 << (8-bit-1) ? 0 : 255);
  97.             }
  98.         }
  99.     }
  100.     return 0;
  101. }
  102.  
  103. int pm_bitstomaxval(int const bits)
  104. {
  105.     return ( 1 << bits ) - 1;
  106. }
  107.  
  108. int __stdcall _open_jbig(CImage &timg, char *path, int showerrdetails)
  109. {
  110.     FILE *fin;
  111.     int result;
  112.     int all_args = 0, files = 0;
  113.     struct jbg_dec_state s;
  114.     char *buffer;
  115.     unsigned char *p;
  116.     size_t len, cnt;
  117.     unsigned long xmax = 4294967295UL, ymax = 4294967295UL;
  118.     int plane = -1, use_graycode = 1, diagnose = 0;
  119.     int rv=0;
  120.     CImage *img=&timg;
  121.     
  122.     open_jbig_cursor=0;
  123.     buffer = (char*)malloc(open_jbig_bufsize);
  124.     if (!buffer) {
  125.         return OUT_OF_MEMORY;
  126.     }
  127.     
  128.     fin=fopen(path, "rb");
  129.     if (fin==NULL) {
  130.         free(buffer);
  131.         return FILE_ERROR;
  132.     }
  133.     
  134.     //send input file to decoder
  135.     jbg_dec_init(&s);
  136.     jbg_dec_maxsize(&s, xmax, ymax);
  137.     result = JBG_EAGAIN;
  138.     do {
  139.         len = fread(buffer, 1, open_jbig_bufsize, fin);
  140.         if (!len) break;
  141.         cnt = 0;
  142.         p = (unsigned char *) buffer;
  143.         while (len > 0 && (result == JBG_EAGAIN || result == JBG_EOK)) {
  144.             result = jbg_dec_in(&s, p, len, &cnt);
  145.             p += cnt;
  146.             len -= cnt;
  147.         }
  148.     } while (result == JBG_EAGAIN || result == JBG_EOK);
  149.     
  150.     if (ferror(fin)) {
  151.         if (showerrdetails) MsgBox(MB_OK|MB_ICONSTOP, "Problem while reading input file '%s", path);
  152.         fclose(fin);
  153.         free(buffer);
  154.         return UNSUP_FORMAT;
  155.     }
  156.  
  157.     if (result != JBG_EOK && result != JBG_EOK_INTR) {
  158.         if (showerrdetails) MsgBox(MB_OK|MB_ICONSTOP, "Problem with input file '%s': %s\n", path, jbg_strerror(result, JBG_EN));
  159.         fclose(fin);
  160.         free(buffer);
  161.         return UNSUP_FORMAT;
  162.     }
  163.  
  164.     if (plane >= 0 && jbg_dec_getplanes(&s) <= plane) {
  165.         if (showerrdetails) MsgBox(MB_OK|MB_ICONSTOP, "Image has only %d planes!\n", jbg_dec_getplanes(&s));
  166.         fclose(fin);
  167.         free(buffer);
  168.         return UNSUP_FORMAT;
  169.     }
  170.     
  171.     {
  172.         //Write it out
  173.         
  174.         int rows, cols;
  175.         int maxval;
  176.         int bpp;
  177.         int plane_to_write;
  178.         
  179.         cols = jbg_dec_getwidth(&s);
  180.         rows = jbg_dec_getheight(&s);
  181.         maxval = pm_bitstomaxval(jbg_dec_getplanes(&s));
  182.         bpp = (jbg_dec_getplanes(&s)+7)/8;
  183.         
  184.         if (jbg_dec_getplanes(&s) == 1) 
  185.             plane_to_write = 0;
  186.         else 
  187.             plane_to_write = plane;
  188.         
  189.         if (plane_to_write >= 0) {
  190.             BYTE* binary_image;
  191.             
  192.             binary_image=jbg_dec_getimage(&s, plane_to_write);
  193.             rv=open_jbig_write_raw_pbm(img, binary_image, rows, cols);
  194.             
  195.         } else {
  196.             BYTE* image;
  197.             
  198.             image = (BYTE*)malloc(cols*rows*bpp);
  199.             jbg_dec_merge_planes(&s, use_graycode, open_jbig_collect_image, image);
  200.             rv=open_jbig_write_pnm(img, image, bpp, rows, cols, maxval, 1);
  201.             free(image);
  202.         }
  203.     }
  204.     
  205.     fclose(fin);
  206.     free(buffer);
  207.     jbg_dec_free(&s);
  208.     return rv;
  209. }
  210.  
  211. void save_jbig_data_out(unsigned char *start, size_t len, void *file)
  212. {
  213.     fwrite(start, len, 1, (FILE *) file);
  214. }
  215.  
  216. int pm_maxvaltobits(int const maxval)
  217. {
  218.     if ( maxval <= 1 )
  219.         return 1;
  220.     else if ( maxval <= 3 )
  221.         return 2;
  222.     else if ( maxval <= 7 )
  223.         return 3;
  224.     else if ( maxval <= 15 )
  225.         return 4;
  226.     else if ( maxval <= 31 )
  227.         return 5;
  228.     else if ( maxval <= 63 )
  229.         return 6;
  230.     else if ( maxval <= 127 )
  231.         return 7;
  232.     else if ( maxval <= 255 )
  233.         return 8;
  234.     else if ( maxval <= 511 )
  235.         return 9;
  236.     else if ( maxval <= 1023 )
  237.         return 10;
  238.     else if ( maxval <= 2047 )
  239.         return 11;
  240.     else if ( maxval <= 4095 )
  241.         return 12;
  242.     else if ( maxval <= 8191 )
  243.         return 13;
  244.     else if ( maxval <= 16383 )
  245.         return 14;
  246.     else if ( maxval <= 32767 )
  247.         return 15;
  248.     else if ( (long) maxval <= 65535L )
  249.         return 16;
  250.     else
  251.         return -1;
  252. }
  253.  
  254. int __stdcall _save_jbig(CImage &timg, char *path, int grey)
  255. {
  256.     FILE *fout;
  257.     int all_args = 0, files = 0;
  258.     int bpp, planes, encode_planes = -1;
  259.     int cols, rows;
  260.     int bytes_per_line;
  261.     unsigned char **bitmap;
  262.     unsigned char *image;
  263.     struct jbg_enc_state s;
  264.     int verbose = 0, delay_at = 0, use_graycode = 1;
  265.     long mwidth = 640, mheight = 480;
  266.     int dl = -1, dh = -1, d = -1, l0 = -1, mx = -1;
  267.     int options = JBG_TPDON | JBG_TPBON | JBG_DPON;
  268.     int order = JBG_ILEAVE | JBG_SMID;
  269.     CImage *img=&timg;
  270.  
  271.     fout=fopen(path, "wb");
  272.     if (fout==NULL)
  273.         return FILE_ERROR;
  274.  
  275.     if (!grey)
  276.         use_graycode = 0;
  277.  
  278.     cols=UVImage_getXSize(img);
  279.     rows=UVImage_getYSize(img);
  280.     
  281.     UVImage_colortable_make(img);
  282.     if (!UVImage_colortable_isblackwhite(img)) {
  283.         if (grey&&!UVImage_colortable_isgreyscale(img))
  284.             UVImage_effect_makegray_light(img);
  285.         else if (!grey)
  286.             UVImage_quantize(img, 2, 5);
  287.     }
  288.     UVImage_colortable_free(img);
  289.  
  290.     planes=pm_maxvaltobits(UVImage_getBPP(img)==1?1:255);
  291.     
  292.     bpp = (planes + 7) / 8;
  293.  
  294.     if (encode_planes < 0 || encode_planes > planes)
  295.         encode_planes = planes;
  296.     bytes_per_line = (cols + 7) / 8;
  297.     
  298.     image = (BYTE*)malloc(cols * rows * bpp);
  299.     if (image==NULL) {
  300.         fclose(fout);
  301.         return OUT_OF_MEMORY;
  302.     }
  303.     
  304.     int row;
  305.     for (row = 0; row < rows; row++) {
  306.         int col;
  307.         for (col = 0; col < cols; col++) {
  308.             int j;
  309.             for (j = 0; j < bpp; j++)
  310.                 image[(((row*cols)+col) * bpp) + j]=UVImage_getL(img, col, row) >> ((bpp-1-j) * 8);
  311.         }
  312.     }
  313.     
  314.     int i;
  315.     
  316.     bitmap = (unsigned char **) malloc(sizeof(unsigned char *) * encode_planes);
  317.     if (bitmap==NULL) {
  318.         free(image);
  319.         fclose(fout);
  320.         return OUT_OF_MEMORY;
  321.     }
  322.  
  323.     for (i = 0; i < encode_planes; i++) {
  324.         bitmap[i] = (unsigned char *) malloc(bytes_per_line * rows);
  325.         if (bitmap[i]==NULL) {
  326.             int j;
  327.             for (j=0; j<i; j++)
  328.                 free(bitmap[i]);
  329.             free(bitmap);
  330.             free(image);
  331.             fclose(fout);
  332.             return OUT_OF_MEMORY;
  333.         }
  334.     }
  335.     
  336.     jbg_split_planes(cols, rows, planes, encode_planes, image, bitmap, use_graycode);
  337.     free(image);
  338.     
  339.     if (encode_planes == 1) {
  340.         int row;
  341.         for (row = 0; row < rows; row++) {
  342.             int i;
  343.             for (i = 0; i < bytes_per_line; i++)
  344.                 bitmap[0][(row*bytes_per_line) + i] ^= 0xff;
  345.         }
  346.     }
  347.     
  348.     jbg_enc_init(&s, cols, rows, encode_planes, bitmap, save_jbig_data_out, fout);
  349.     
  350.     if (d >= 0)
  351.         jbg_enc_layers(&s, d);
  352.     else
  353.         jbg_enc_lrlmax(&s, mwidth, mheight);
  354.     
  355.     if (delay_at)
  356.         options |= JBG_DELAY_AT;
  357.     jbg_enc_lrange(&s, dl, dh);
  358.     jbg_enc_options(&s, order, options, l0, mx, -1);
  359.     
  360.     jbg_enc_out(&s);
  361.     
  362.     jbg_enc_free(&s);
  363.  
  364.     for (i=0; i<encode_planes; i++)
  365.         free(bitmap[i]);
  366.     free(bitmap);
  367.     fclose(fout);
  368.     return 0;
  369. }
  370.  
  371. int uvplugin_init(up_initdata* updata)
  372. {
  373.     updata->items_count=0;
  374.     strcpy(updata->plugin_name, "JBIG import/export filter (us)");
  375.  
  376.     updata->version_1=1;
  377.     updata->version_2=8;
  378.     return 0;
  379. }
  380.  
  381. int __stdcall uvplugin_main(HINSTANCE plgI, DWORD message, DWORD wParam, DWORD lParam)
  382. {
  383.     switch (message) {
  384.     case UVMSG_INITPLUGIN:
  385.         return uvplugin_init((up_initdata*)wParam);
  386.     case UVMSG_EXIT:
  387.         return 0;
  388.     case UVMSG_STOPEXIT:
  389.         return 0;
  390.     }
  391.     return 0;
  392. }