about summary refs log tree commit diff
path: root/converter/other/giftopnm.c
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2009-05-02 19:23:42 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2009-05-02 19:23:42 +0000
commitd183dec220bbedbcac8081dc6fa5a81dde9b23f3 (patch)
treeea0d1ec4702cccffe551cab493ff79ab20bd869b /converter/other/giftopnm.c
parent3fb9822420a65f1fa543e99edb55244ddf2a333a (diff)
downloadnetpbm-mirror-d183dec220bbedbcac8081dc6fa5a81dde9b23f3.tar.gz
netpbm-mirror-d183dec220bbedbcac8081dc6fa5a81dde9b23f3.tar.xz
netpbm-mirror-d183dec220bbedbcac8081dc6fa5a81dde9b23f3.zip
Extract whole bytes or words instead of a bit at a time
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@908 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/other/giftopnm.c')
-rw-r--r--converter/other/giftopnm.c56
1 files changed, 48 insertions, 8 deletions
diff --git a/converter/other/giftopnm.c b/converter/other/giftopnm.c
index 32023dce..4d2d720b 100644
--- a/converter/other/giftopnm.c
+++ b/converter/other/giftopnm.c
@@ -42,6 +42,13 @@
 #define LOCALCOLORMAP  0x80
 #define BitSet(byte, bit)      (((byte) & (bit)) == (bit))
 
+#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN)
+  /* make sure (BYTE_ORDER == LITTLE_ENDIAN) is FALSE */ 
+  #define BYTE_ORDER    0
+  #define LITTLE_ENDIAN 1
+#endif
+
+
 static __inline__ bool
 ReadOK(FILE *          const fileP,
        unsigned char * const buffer,
@@ -561,6 +568,45 @@ getCode_init(struct getCodeState * const getCodeStateP) {
 
 
 
+static unsigned int
+bitsOfLeBuffer(const unsigned char * const buf,
+               unsigned int          const start,
+               unsigned int          const len) {
+/*----------------------------------------------------------------------------
+   Return a string of 'len' bits (up to 16) starting at bit 'start' of buffer
+   buf[].
+
+   In the buffer, the bits are numbered Intel-style, with the first bit of a
+   byte being the least significant bit.  So bit 3 is the "16" bit of the
+   first byte of buf[].
+
+   We return the string as an integer such that its pure binary encoding with
+   the bits numbered Intel-style is the string.  E.g. the string 0,1,1 
+   yields six.
+-----------------------------------------------------------------------------*/
+    uint32_t codeBlock;
+        /* The 3 whole bytes of the buffer that contain the requested
+           bit string
+        */
+
+    assert(len <= 16);
+
+    if (BYTE_ORDER == LITTLE_ENDIAN)
+        /* Fast path */
+        codeBlock = *(uint32_t *) & buf[start/8];
+    else
+        /* logic works for little endian too */
+        codeBlock =
+            (buf[start/8+0] <<  0) |
+            (buf[start/8+1] <<  8) |
+            (buf[start/8+2] << 16);
+            
+    return (unsigned int) 
+        (codeBlock >> (start % 8)) & ((1 << len) - 1);
+}
+
+
+
 static void
 getCode_get(struct getCodeState * const gsP,
             FILE *                const ifP, 
@@ -613,16 +659,10 @@ getCode_get(struct getCodeState * const gsP,
                                bitsUnused, codeSize);
             }
         } else {
-            int i, j;
-            unsigned int code;
-            unsigned char * const buf = gsP->buf;
-            
-            code = 0;  /* initial value */
-            for (i = gsP->curbit, j = 0; j < codeSize; ++i, ++j)
-                code |= ((buf[ i / 8 ] & (1 << (i % 8))) != 0) << j;
+            *codeP = bitsOfLeBuffer(gsP->buf, gsP->curbit, codeSize);
+
             gsP->curbit += codeSize;
             *eofP = FALSE;
-            *codeP = code;
         }
     }
 }