Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

src/main/bit-ops.c

Go to the documentation of this file.
00001 /*
00002  * "$Id: bit-ops.c,v 1.6 2004/05/07 19:20:28 rleigh Exp $"
00003  *
00004  *   Softweave calculator for gimp-print.
00005  *
00006  *   Copyright 2000 Charles Briscoe-Smith <cpbs@debian.org>
00007  *
00008  *   This program is free software; you can redistribute it and/or modify it
00009  *   under the terms of the GNU General Public License as published by the Free
00010  *   Software Foundation; either version 2 of the License, or (at your option)
00011  *   any later version.
00012  *
00013  *   This program is distributed in the hope that it will be useful, but
00014  *   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00015  *   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00016  *   for more details.
00017  *
00018  *   You should have received a copy of the GNU General Public License
00019  *   along with this program; if not, write to the Free Software
00020  *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00021  */
00022 
00023 /*
00024  * This file must include only standard C header files.  The core code must
00025  * compile on generic platforms that don't support glib, gimp, gtk, etc.
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 #include <string.h>
00032 #include <gimp-print/gimp-print.h>
00033 #include "gimp-print-internal.h"
00034 #include <gimp-print/gimp-print-intl-internal.h>
00035 #ifdef HAVE_LIMITS_H
00036 #include <limits.h>
00037 #endif
00038 
00039 void
00040 stp_fold(const unsigned char *line,
00041          int single_length,
00042          unsigned char *outbuf)
00043 {
00044   int i;
00045   memset(outbuf, 0, single_length * 2);
00046   for (i = 0; i < single_length; i++)
00047     {
00048       unsigned char l0 = line[0];
00049       unsigned char l1 = line[single_length];
00050       if (l0 || l1)
00051         {
00052           outbuf[0] =
00053             ((l0 & (1 << 7)) >> 1) +
00054             ((l0 & (1 << 6)) >> 2) +
00055             ((l0 & (1 << 5)) >> 3) +
00056             ((l0 & (1 << 4)) >> 4) +
00057             ((l1 & (1 << 7)) >> 0) +
00058             ((l1 & (1 << 6)) >> 1) +
00059             ((l1 & (1 << 5)) >> 2) +
00060             ((l1 & (1 << 4)) >> 3);
00061           outbuf[1] =
00062             ((l0 & (1 << 3)) << 3) +
00063             ((l0 & (1 << 2)) << 2) +
00064             ((l0 & (1 << 1)) << 1) +
00065             ((l0 & (1 << 0)) << 0) +
00066             ((l1 & (1 << 3)) << 4) +
00067             ((l1 & (1 << 2)) << 3) +
00068             ((l1 & (1 << 1)) << 2) +
00069             ((l1 & (1 << 0)) << 1);
00070         }
00071       line++;
00072       outbuf += 2;
00073     }
00074 }
00075 
00076 static void
00077 stpi_split_2_1(int length,
00078                const unsigned char *in,
00079                unsigned char *outhi,
00080                unsigned char *outlo)
00081 {
00082   unsigned char *outs[2];
00083   int i;
00084   int row = 0;
00085   int limit = length;
00086   outs[0] = outhi;
00087   outs[1] = outlo;
00088   memset(outs[1], 0, limit);
00089   for (i = 0; i < limit; i++)
00090     {
00091       unsigned char inbyte = in[i];
00092       outs[0][i] = 0;
00093       if (inbyte == 0)
00094         continue;
00095       /* For some reason gcc isn't unrolling this, even with -funroll-loops */
00096       if (inbyte & 1)
00097         {
00098           outs[row][i] |= 1 & inbyte;
00099           row = row ^ 1;
00100         }
00101       if (inbyte & (1 << 1))
00102         {
00103           outs[row][i] |= (1 << 1) & inbyte;
00104           row = row ^ 1;
00105         }
00106       if (inbyte & (1 << 2))
00107         {
00108           outs[row][i] |= (1 << 2) & inbyte;
00109           row = row ^ 1;
00110         }
00111       if (inbyte & (1 << 3))
00112         {
00113           outs[row][i] |= (1 << 3) & inbyte;
00114           row = row ^ 1;
00115         }
00116       if (inbyte & (1 << 4))
00117         {
00118           outs[row][i] |= (1 << 4) & inbyte;
00119           row = row ^ 1;
00120         }
00121       if (inbyte & (1 << 5))
00122         {
00123           outs[row][i] |= (1 << 5) & inbyte;
00124           row = row ^ 1;
00125         }
00126       if (inbyte & (1 << 6))
00127         {
00128           outs[row][i] |= (1 << 6) & inbyte;
00129           row = row ^ 1;
00130         }
00131       if (inbyte & (1 << 7))
00132         {
00133           outs[row][i] |= (1 << 7) & inbyte;
00134           row = row ^ 1;
00135         }
00136     }
00137 }
00138 
00139 static void
00140 stp_split_2_2(int length,
00141               const unsigned char *in,
00142               unsigned char *outhi,
00143               unsigned char *outlo)
00144 {
00145   unsigned char *outs[2];
00146   int i;
00147   unsigned row = 0;
00148   int limit = length * 2;
00149   outs[0] = outhi;
00150   outs[1] = outlo;
00151   memset(outs[1], 0, limit);
00152   for (i = 0; i < limit; i++)
00153     {
00154       unsigned char inbyte = in[i];
00155       outs[0][i] = 0;
00156       if (inbyte == 0)
00157         continue;
00158       /* For some reason gcc isn't unrolling this, even with -funroll-loops */
00159       if (inbyte & 3)
00160         {
00161           outs[row][i] |= (3 & inbyte);
00162           row = row ^ 1;
00163         }
00164       if (inbyte & (3 << 2))
00165         {
00166           outs[row][i] |= ((3 << 2) & inbyte);
00167           row = row ^ 1;
00168         }
00169       if (inbyte & (3 << 4))
00170         {
00171           outs[row][i] |= ((3 << 4) & inbyte);
00172           row = row ^ 1;
00173         }
00174       if (inbyte & (3 << 6))
00175         {
00176           outs[row][i] |= ((3 << 6) & inbyte);
00177           row = row ^ 1;
00178         }
00179     }
00180 }
00181 
00182 void
00183 stp_split_2(int length,
00184             int bits,
00185             const unsigned char *in,
00186             unsigned char *outhi,
00187             unsigned char *outlo)
00188 {
00189   if (bits == 2)
00190     stp_split_2_2(length, in, outhi, outlo);
00191   else
00192     stpi_split_2_1(length, in, outhi, outlo);
00193 }
00194 
00195 static void
00196 stpi_split_4_1(int length,
00197                const unsigned char *in,
00198                unsigned char *out0,
00199                unsigned char *out1,
00200                unsigned char *out2,
00201                unsigned char *out3)
00202 {
00203   unsigned char *outs[4];
00204   int i;
00205   int row = 0;
00206   int limit = length;
00207   outs[0] = out0;
00208   outs[1] = out1;
00209   outs[2] = out2;
00210   outs[3] = out3;
00211   memset(outs[1], 0, limit);
00212   memset(outs[2], 0, limit);
00213   memset(outs[3], 0, limit);
00214   for (i = 0; i < limit; i++)
00215     {
00216       unsigned char inbyte = in[i];
00217       outs[0][i] = 0;
00218       if (inbyte == 0)
00219         continue;
00220       /* For some reason gcc isn't unrolling this, even with -funroll-loops */
00221       if (inbyte & 1)
00222         {
00223           outs[row][i] |= 1 & inbyte;
00224           row = (row + 1) & 3;
00225         }
00226       if (inbyte & (1 << 1))
00227         {
00228           outs[row][i] |= (1 << 1) & inbyte;
00229           row = (row + 1) & 3;
00230         }
00231       if (inbyte & (1 << 2))
00232         {
00233           outs[row][i] |= (1 << 2) & inbyte;
00234           row = (row + 1) & 3;
00235         }
00236       if (inbyte & (1 << 3))
00237         {
00238           outs[row][i] |= (1 << 3) & inbyte;
00239           row = (row + 1) & 3;
00240         }
00241       if (inbyte & (1 << 4))
00242         {
00243           outs[row][i] |= (1 << 4) & inbyte;
00244           row = (row + 1) & 3;
00245         }
00246       if (inbyte & (1 << 5))
00247         {
00248           outs[row][i] |= (1 << 5) & inbyte;
00249           row = (row + 1) & 3;
00250         }
00251       if (inbyte & (1 << 6))
00252         {
00253           outs[row][i] |= (1 << 6) & inbyte;
00254           row = (row + 1) & 3;
00255         }
00256       if (inbyte & (1 << 7))
00257         {
00258           outs[row][i] |= (1 << 7) & inbyte;
00259           row = (row + 1) & 3;
00260         }
00261     }
00262 }
00263 
00264 static void
00265 stpi_split_4_2(int length,
00266                const unsigned char *in,
00267                unsigned char *out0,
00268                unsigned char *out1,
00269                unsigned char *out2,
00270                unsigned char *out3)
00271 {
00272   unsigned char *outs[4];
00273   int i;
00274   int row = 0;
00275   int limit = length * 2;
00276   outs[0] = out0;
00277   outs[1] = out1;
00278   outs[2] = out2;
00279   outs[3] = out3;
00280   memset(outs[1], 0, limit);
00281   memset(outs[2], 0, limit);
00282   memset(outs[3], 0, limit);
00283   for (i = 0; i < limit; i++)
00284     {
00285       unsigned char inbyte = in[i];
00286       outs[0][i] = 0;
00287       if (inbyte == 0)
00288         continue;
00289       /* For some reason gcc isn't unrolling this, even with -funroll-loops */
00290       if (inbyte & 3)
00291         {
00292           outs[row][i] |= 3 & inbyte;
00293           row = (row + 1) & 3;
00294         }
00295       if (inbyte & (3 << 2))
00296         {
00297           outs[row][i] |= (3 << 2) & inbyte;
00298           row = (row + 1) & 3;
00299         }
00300       if (inbyte & (3 << 4))
00301         {
00302           outs[row][i] |= (3 << 4) & inbyte;
00303           row = (row + 1) & 3;
00304         }
00305       if (inbyte & (3 << 6))
00306         {
00307           outs[row][i] |= (3 << 6) & inbyte;
00308           row = (row + 1) & 3;
00309         }
00310     }
00311 }
00312 
00313 void
00314 stp_split_4(int length,
00315             int bits,
00316             const unsigned char *in,
00317             unsigned char *out0,
00318             unsigned char *out1,
00319             unsigned char *out2,
00320             unsigned char *out3)
00321 {
00322   if (bits == 2)
00323     stpi_split_4_2(length, in, out0, out1, out2, out3);
00324   else
00325     stpi_split_4_1(length, in, out0, out1, out2, out3);
00326 }
00327 
00328 
00329 #if __BYTE_ORDER == __LITTLE_ENDIAN
00330 #define SH20 0
00331 #define SH21 8
00332 #else
00333 #define SH20 8
00334 #define SH21 0
00335 #endif
00336 
00337 static void
00338 stpi_unpack_2_1(int length,
00339                 const unsigned char *in,
00340                 unsigned char *out0,
00341                 unsigned char *out1)
00342 {
00343   unsigned char tempin, bit, temp0, temp1;
00344 
00345   if (length <= 0)
00346     return;
00347   for (bit = 128, temp0 = 0, temp1 = 0;
00348        length > 0;
00349        length --)
00350     {
00351       tempin = *in++;
00352 
00353       if (tempin & 128)
00354         temp0 |= bit;
00355       if (tempin & 64)
00356         temp1 |= bit;
00357       bit >>= 1;
00358       if (tempin & 32)
00359         temp0 |= bit;
00360       if (tempin & 16)
00361         temp1 |= bit;
00362       bit >>= 1;
00363       if (tempin & 8)
00364         temp0 |= bit;
00365       if (tempin & 4)
00366         temp1 |= bit;
00367       bit >>= 1;
00368       if (tempin & 2)
00369         temp0 |= bit;
00370       if (tempin & 1)
00371         temp1 |= bit;
00372 
00373       if (bit > 1)
00374         bit >>= 1;
00375       else
00376       {
00377         bit     = 128;
00378         *out0++ = temp0;
00379         *out1++ = temp1;
00380 
00381         temp0   = 0;
00382         temp1   = 0;
00383       }
00384     }
00385 
00386   if (bit < 128)
00387     {
00388       *out0++ = temp0;
00389       *out1++ = temp1;
00390     }
00391 }
00392 
00393 static void
00394 stpi_unpack_2_2(int length,
00395                const unsigned char *in,
00396                unsigned char *out0,
00397                unsigned char *out1)
00398 {
00399   if (length <= 0)
00400     return;
00401 
00402   for (;length;length --)
00403     {
00404       unsigned char ti0, ti1;
00405       ti0 = in[0];
00406       ti1 = in[1];
00407 
00408       *out0++  = (ti0 & 0xc0) << 0
00409         | (ti0 & 0x0c) << 2
00410         | (ti1 & 0xc0) >> 4
00411         | (ti1 & 0x0c) >> 2;
00412       *out1++  = (ti0 & 0x30) << 2
00413         | (ti0 & 0x03) << 4
00414         | (ti1 & 0x30) >> 2
00415         | (ti1 & 0x03) >> 0;
00416       in += 2;
00417     }
00418 }
00419 
00420 void
00421 stp_unpack_2(int length,
00422              int bits,
00423              const unsigned char *in,
00424              unsigned char *outlo,
00425              unsigned char *outhi)
00426 {
00427   if (bits == 1)
00428     stpi_unpack_2_1(length, in, outlo, outhi);
00429   else
00430     stpi_unpack_2_2(length, in, outlo, outhi);
00431 }
00432 
00433 #if __BYTE_ORDER == __LITTLE_ENDIAN
00434 #define SH40 0
00435 #define SH41 8
00436 #define SH42 16
00437 #define SH43 24
00438 #else
00439 #define SH40 24
00440 #define SH41 16
00441 #define SH42 8
00442 #define SH43 0
00443 #endif
00444 
00445 static void
00446 stpi_unpack_4_1(int length,
00447                  const unsigned char *in,
00448                  unsigned char *out0,
00449                  unsigned char *out1,
00450                  unsigned char *out2,
00451                  unsigned char *out3)
00452 {
00453   unsigned char tempin, bit, temp0, temp1, temp2, temp3;
00454 
00455   if (length <= 0)
00456     return;
00457   for (bit = 128, temp0 = 0, temp1 = 0, temp2 = 0, temp3 = 0;
00458        length > 0;
00459        length --)
00460     {
00461       tempin = *in++;
00462 
00463       if (tempin & 128)
00464         temp0 |= bit;
00465       if (tempin & 64)
00466         temp1 |= bit;
00467       if (tempin & 32)
00468         temp2 |= bit;
00469       if (tempin & 16)
00470         temp3 |= bit;
00471       bit >>= 1;
00472       if (tempin & 8)
00473         temp0 |= bit;
00474       if (tempin & 4)
00475         temp1 |= bit;
00476       if (tempin & 2)
00477         temp2 |= bit;
00478       if (tempin & 1)
00479         temp3 |= bit;
00480 
00481       if (bit > 1)
00482         bit >>= 1;
00483       else
00484       {
00485         bit     = 128;
00486         *out0++ = temp0;
00487         *out1++ = temp1;
00488         *out2++ = temp2;
00489         *out3++ = temp3;
00490 
00491         temp0   = 0;
00492         temp1   = 0;
00493         temp2   = 0;
00494         temp3   = 0;
00495       }
00496     }
00497 
00498   if (bit < 128)
00499     {
00500       *out0++ = temp0;
00501       *out1++ = temp1;
00502       *out2++ = temp2;
00503       *out3++ = temp3;
00504     }
00505 }
00506 
00507 static void
00508 stpi_unpack_4_2(int length,
00509                  const unsigned char *in,
00510                  unsigned char *out0,
00511                  unsigned char *out1,
00512                  unsigned char *out2,
00513                  unsigned char *out3)
00514 {
00515   unsigned char tempin,
00516                 shift,
00517                 temp0,
00518                 temp1,
00519                 temp2,
00520                 temp3;
00521 
00522   length *= 2;
00523 
00524   for (shift = 0, temp0 = 0, temp1 = 0, temp2 = 0, temp3 = 0;
00525        length > 0;
00526        length --)
00527     {
00528      /*
00529       * Note - we can't use (tempin & N) >> (shift - M) since negative
00530       * right-shifts are not always implemented.
00531       */
00532 
00533       tempin = *in++;
00534 
00535       if (tempin & 192)
00536         temp0 |= (tempin & 192) >> shift;
00537       if (tempin & 48)
00538         temp1 |= ((tempin & 48) << 2) >> shift;
00539       if (tempin & 12)
00540         temp2 |= ((tempin & 12) << 4) >> shift;
00541       if (tempin & 3)
00542         temp3 |= ((tempin & 3) << 6) >> shift;
00543 
00544       if (shift < 6)
00545         shift += 2;
00546       else
00547       {
00548         shift   = 0;
00549         *out0++ = temp0;
00550         *out1++ = temp1;
00551         *out2++ = temp2;
00552         *out3++ = temp3;
00553 
00554         temp0   = 0;
00555         temp1   = 0;
00556         temp2   = 0;
00557         temp3   = 0;
00558       }
00559     }
00560 
00561   if (shift)
00562     {
00563       *out0++ = temp0;
00564       *out1++ = temp1;
00565       *out2++ = temp2;
00566       *out3++ = temp3;
00567     }
00568 }
00569 
00570 void
00571 stp_unpack_4(int length,
00572              int bits,
00573              const unsigned char *in,
00574              unsigned char *out0,
00575              unsigned char *out1,
00576              unsigned char *out2,
00577              unsigned char *out3)
00578 {
00579   if (bits == 1)
00580     stpi_unpack_4_1(length, in, out0, out1, out2, out3);
00581   else
00582     stpi_unpack_4_2(length, in, out0, out1, out2, out3);
00583 }
00584 
00585 static void
00586 stpi_unpack_8_1(int length,
00587                 const unsigned char *in,
00588                 unsigned char *out0,
00589                 unsigned char *out1,
00590                 unsigned char *out2,
00591                 unsigned char *out3,
00592                 unsigned char *out4,
00593                 unsigned char *out5,
00594                 unsigned char *out6,
00595                 unsigned char *out7)
00596 {
00597   unsigned char tempin, bit, temp0, temp1, temp2, temp3, temp4, temp5, temp6,
00598     temp7;
00599 
00600   if (length <= 0)
00601     return;
00602 
00603   for (bit = 128, temp0 = 0, temp1 = 0, temp2 = 0,
00604        temp3 = 0, temp4 = 0, temp5 = 0, temp6 = 0, temp7 = 0;
00605        length > 0;
00606        length --)
00607     {
00608       tempin = *in++;
00609 
00610       if (tempin & 128)
00611         temp0 |= bit;
00612       if (tempin & 64)
00613         temp1 |= bit;
00614       if (tempin & 32)
00615         temp2 |= bit;
00616       if (tempin & 16)
00617         temp3 |= bit;
00618       if (tempin & 8)
00619         temp4 |= bit;
00620       if (tempin & 4)
00621         temp5 |= bit;
00622       if (tempin & 2)
00623         temp6 |= bit;
00624       if (tempin & 1)
00625         temp7 |= bit;
00626 
00627       if (bit > 1)
00628         bit >>= 1;
00629       else
00630       {
00631         bit     = 128;
00632         *out0++ = temp0;
00633         *out1++ = temp1;
00634         *out2++ = temp2;
00635         *out3++ = temp3;
00636         *out4++ = temp4;
00637         *out5++ = temp5;
00638         *out6++ = temp6;
00639         *out7++ = temp7;
00640 
00641         temp0   = 0;
00642         temp1   = 0;
00643         temp2   = 0;
00644         temp3   = 0;
00645         temp4   = 0;
00646         temp5   = 0;
00647         temp6   = 0;
00648         temp7   = 0;
00649       }
00650     }
00651 
00652   if (bit < 128)
00653     {
00654       *out0++ = temp0;
00655       *out1++ = temp1;
00656       *out2++ = temp2;
00657       *out3++ = temp3;
00658       *out4++ = temp4;
00659       *out5++ = temp5;
00660       *out6++ = temp6;
00661       *out7++ = temp7;
00662     }
00663 }
00664 
00665 static void
00666 stpi_unpack_8_2(int length,
00667                 const unsigned char *in,
00668                 unsigned char *out0,
00669                 unsigned char *out1,
00670                 unsigned char *out2,
00671                 unsigned char *out3,
00672                 unsigned char *out4,
00673                 unsigned char *out5,
00674                 unsigned char *out6,
00675                 unsigned char *out7)
00676 {
00677   unsigned char tempin,
00678                 shift,
00679                 temp0,
00680                 temp1,
00681                 temp2,
00682                 temp3,
00683                 temp4,
00684                 temp5,
00685                 temp6,
00686                 temp7;
00687 
00688 
00689   for (shift = 0, temp0 = 0, temp1 = 0,
00690        temp2 = 0, temp3 = 0, temp4 = 0, temp5 = 0, temp6 = 0, temp7 = 0;
00691        length > 0;
00692        length --)
00693     {
00694      /*
00695       * Note - we can't use (tempin & N) >> (shift - M) since negative
00696       * right-shifts are not always implemented.
00697       */
00698 
00699       tempin = *in++;
00700 
00701       if (tempin & 192)
00702         temp0 |= (tempin & 192) >> shift;
00703       if (tempin & 48)
00704         temp1 |= ((tempin & 48) << 2) >> shift;
00705       if (tempin & 12)
00706         temp2 |= ((tempin & 12) << 4) >> shift;
00707       if (tempin & 3)
00708         temp3 |= ((tempin & 3) << 6) >> shift;
00709 
00710       tempin = *in++;
00711 
00712       if (tempin & 192)
00713         temp4 |= (tempin & 192) >> shift;
00714       if (tempin & 48)
00715         temp5 |= ((tempin & 48) << 2) >> shift;
00716       if (tempin & 12)
00717         temp6 |= ((tempin & 12) << 4) >> shift;
00718       if (tempin & 3)
00719         temp7 |= ((tempin & 3) << 6) >> shift;
00720 
00721       if (shift < 6)
00722         shift += 2;
00723       else
00724       {
00725         shift   = 0;
00726         *out0++ = temp0;
00727         *out1++ = temp1;
00728         *out2++ = temp2;
00729         *out3++ = temp3;
00730         *out4++ = temp4;
00731         *out5++ = temp5;
00732         *out6++ = temp6;
00733         *out7++ = temp7;
00734 
00735         temp0   = 0;
00736         temp1   = 0;
00737         temp2   = 0;
00738         temp3   = 0;
00739         temp4   = 0;
00740         temp5   = 0;
00741         temp6   = 0;
00742         temp7   = 0;
00743       }
00744     }
00745 
00746   if (shift)
00747     {
00748       *out0++ = temp0;
00749       *out1++ = temp1;
00750       *out2++ = temp2;
00751       *out3++ = temp3;
00752       *out4++ = temp4;
00753       *out5++ = temp5;
00754       *out6++ = temp6;
00755       *out7++ = temp7;
00756     }
00757 }
00758 
00759 void
00760 stp_unpack_8(int length,
00761              int bits,
00762              const unsigned char *in,
00763              unsigned char *out0,
00764              unsigned char *out1,
00765              unsigned char *out2,
00766              unsigned char *out3,
00767              unsigned char *out4,
00768              unsigned char *out5,
00769              unsigned char *out6,
00770              unsigned char *out7)
00771 {
00772   if (bits == 1)
00773     stpi_unpack_8_1(length, in, out0, out1, out2, out3,
00774                      out4, out5, out6, out7);
00775   else
00776     stpi_unpack_8_2(length, in, out0, out1, out2, out3,
00777                      out4, out5, out6, out7);
00778 }
00779 
00780 static void
00781 find_first_and_last(const unsigned char *line, int length,
00782                     int *first, int *last)
00783 {
00784   int i;
00785   int found_first = 0;
00786   if (!first || !last)
00787     return;
00788   *first = 0;
00789   *last = 0;
00790   for (i = 0; i < length; i++)
00791     {
00792       if (line[i] == 0)
00793         {
00794           if (!found_first)
00795             (*first)++;
00796         }
00797       else
00798         {
00799           *last = i;
00800           found_first = 1;
00801         }
00802     }
00803 }
00804 
00805 int
00806 stp_pack_uncompressed(stp_vars_t *v,
00807                       const unsigned char *line,
00808                       int length,
00809                       unsigned char *comp_buf,
00810                       unsigned char **comp_ptr,
00811                       int *first,
00812                       int *last)
00813 {
00814   find_first_and_last(line, length, first, last);
00815   memcpy(comp_buf, line, length);
00816   *comp_ptr = comp_buf + length;
00817   if (first > last)
00818     return 0;
00819   else
00820     return 1;
00821 }
00822 
00823 int
00824 stp_pack_tiff(stp_vars_t *v,
00825               const unsigned char *line,
00826               int length,
00827               unsigned char *comp_buf,
00828               unsigned char **comp_ptr,
00829               int *first,
00830               int *last)
00831 {
00832   const unsigned char *start;           /* Start of compressed data */
00833   unsigned char repeat;                 /* Repeating char */
00834   int count;                    /* Count of compressed bytes */
00835   int tcount;                   /* Temporary count < 128 */
00836   register const unsigned char *xline = line;
00837   register int xlength = length;
00838   find_first_and_last(line, length, first, last);
00839 
00840   /*
00841    * Compress using TIFF "packbits" run-length encoding...
00842    */
00843 
00844   (*comp_ptr) = comp_buf;
00845 
00846   while (xlength > 0)
00847     {
00848       /*
00849        * Get a run of non-repeated chars...
00850        */
00851 
00852       start  = xline;
00853       xline   += 2;
00854       xlength -= 2;
00855 
00856       while (xlength > 0 && (xline[-2] != xline[-1] || xline[-1] != xline[0]))
00857         {
00858           xline ++;
00859           xlength --;
00860         }
00861 
00862       xline   -= 2;
00863       xlength += 2;
00864 
00865       /*
00866        * Output the non-repeated sequences (max 128 at a time).
00867        */
00868 
00869       count = xline - start;
00870       while (count > 0)
00871         {
00872           tcount = count > 128 ? 128 : count;
00873 
00874           (*comp_ptr)[0] = tcount - 1;
00875           memcpy((*comp_ptr) + 1, start, tcount);
00876 
00877           (*comp_ptr) += tcount + 1;
00878           start    += tcount;
00879           count    -= tcount;
00880         }
00881 
00882       if (xlength <= 0)
00883         break;
00884 
00885       /*
00886        * Find the repeated sequences...
00887        */
00888 
00889       start  = xline;
00890       repeat = xline[0];
00891 
00892       xline ++;
00893       xlength --;
00894 
00895       if (xlength > 0)
00896         {
00897           int ylength = xlength;
00898           while (ylength && *xline == repeat)
00899             {
00900               xline ++;
00901               ylength --;
00902             }
00903           xlength = ylength;
00904         }
00905 
00906       /*
00907        * Output the repeated sequences (max 128 at a time).
00908        */
00909 
00910       count = xline - start;
00911       while (count > 0)
00912         {
00913           tcount = count > 128 ? 128 : count;
00914 
00915           (*comp_ptr)[0] = 1 - tcount;
00916           (*comp_ptr)[1] = repeat;
00917 
00918           (*comp_ptr) += 2;
00919           count    -= tcount;
00920         }
00921     }
00922   if (first && last && *first > *last)
00923     return 0;
00924   else
00925     return 1;
00926 }

Generated on Wed Aug 25 07:56:13 2004 for libgimpprint API Reference by doxygen 1.3.6