os/ossrv/genericopenlibs/liboil/tsrc/examples/jpeg/src/jpeg_huffman.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     5 * under the terms of "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description: 
    15 *
    16 */
    17 
    18 #include <sys/stat.h>
    19 #include <fcntl.h>
    20 #include <unistd.h>
    21 #include <stdlib.h>
    22 #include <stdio.h>
    23 #include <string.h>
    24 
    25 #include <liboil/liboil.h>
    26 #include <liboil/liboildebug.h>
    27 
    28 #include "jpeg_huffman.h"
    29 #include "jpeg_debug.h"
    30 
    31 /* misc helper function definitions */
    32 
    33 static char *sprintbits (char *str, unsigned int bits, int n);
    34 
    35 
    36 #define TRUE 1
    37 #define FALSE 0
    38 
    39 void
    40 huffman_table_dump (HuffmanTable * table)
    41 {
    42   unsigned int n_bits;
    43   unsigned int code;
    44   char str[33];
    45   int i;
    46   HuffmanEntry *entry;
    47 
    48   OIL_DEBUG ("dumping huffman table %p", table);
    49   for (i = 0; i < table->len; i++) {
    50     entry = table->entries + i;
    51     n_bits = entry->n_bits;
    52     code = entry->symbol >> (16 - n_bits);
    53     sprintbits (str, code, n_bits);
    54     OIL_DEBUG ("%s --> %d", str, entry->value);
    55   }
    56 }
    57 
    58 
    59 
    60 void
    61 huffman_table_init (HuffmanTable *table)
    62 {
    63   memset (table, 0, sizeof(HuffmanTable));
    64 }
    65 
    66 void
    67 huffman_table_add (HuffmanTable * table, uint32_t code, int n_bits, int value)
    68 {
    69   HuffmanEntry *entry = table->entries + table->len;
    70 
    71   entry->value = value;
    72   entry->symbol = code << (16 - n_bits);
    73   entry->mask = 0xffff ^ (0xffff >> n_bits);
    74   entry->n_bits = n_bits;
    75 
    76   table->len++;
    77 }
    78 
    79 unsigned int
    80 huffman_table_decode_jpeg (HuffmanTable * tab, JpegBits * bits)
    81 {
    82   unsigned int code;
    83   int i;
    84   char str[33];
    85   HuffmanEntry *entry;
    86 
    87   code = peekbits (bits, 16);
    88   for (i = 0; i < tab->len; i++) {
    89     entry = tab->entries + i;
    90     if ((code & entry->mask) == entry->symbol) {
    91       code = getbits (bits, entry->n_bits);
    92       sprintbits (str, code, entry->n_bits);
    93       OIL_DEBUG ("%s --> %d", str, entry->value);
    94       return entry->value;
    95     }
    96   }
    97   printf ("huffman sync lost");
    98 
    99   return -1;
   100 }
   101 
   102 int
   103 huffman_table_decode_macroblock (short *block, HuffmanTable * dc_tab,
   104     HuffmanTable * ac_tab, JpegBits * bits)
   105 {
   106   int r, s, x, rs;
   107   int k;
   108   char str[33];
   109 
   110   memset (block, 0, sizeof (short) * 64);
   111 
   112   s = huffman_table_decode_jpeg (dc_tab, bits);
   113   if (s < 0)
   114     return -1;
   115   x = getbits (bits, s);
   116   if ((x >> (s - 1)) == 0) {
   117     x -= (1 << s) - 1;
   118   }
   119   OIL_DEBUG ("s=%d (block[0]=%d)", s, x);
   120   block[0] = x;
   121 
   122   for (k = 1; k < 64; k++) {
   123     rs = huffman_table_decode_jpeg (ac_tab, bits);
   124     if (rs < 0) {
   125       OIL_DEBUG ("huffman error");
   126       return -1;
   127     }
   128     if (bits->ptr > bits->end) {
   129       OIL_DEBUG ("overrun");
   130       return -1;
   131     }
   132     s = rs & 0xf;
   133     r = rs >> 4;
   134     if (s == 0) {
   135       if (r == 15) {
   136         OIL_DEBUG ("r=%d s=%d (skip 16)", r, s);
   137         k += 15;
   138       } else {
   139         OIL_DEBUG ("r=%d s=%d (eob)", r, s);
   140         break;
   141       }
   142     } else {
   143       k += r;
   144       if (k >= 64) {
   145         printf ("macroblock overrun");
   146         return -1;
   147       }
   148       x = getbits (bits, s);
   149       sprintbits (str, x, s);
   150       if ((x >> (s - 1)) == 0) {
   151         x -= (1 << s) - 1;
   152       }
   153       block[k] = x;
   154       OIL_DEBUG ("r=%d s=%d (%s -> block[%d]=%d)", r, s, str, k, x);
   155     }
   156   }
   157   return 0;
   158 }
   159 
   160 int
   161 huffman_table_decode (HuffmanTable * dc_tab, HuffmanTable * ac_tab,
   162     JpegBits * bits)
   163 {
   164   int16_t zz[64];
   165   int ret;
   166 
   167   while (bits->ptr < bits->end) {
   168     ret = huffman_table_decode_macroblock (zz, dc_tab, ac_tab, bits);
   169     if (ret < 0)
   170       return -1;
   171   }
   172 
   173   return 0;
   174 }
   175 
   176 /* misc helper functins */
   177 
   178 static char *
   179 sprintbits (char *str, unsigned int bits, int n)
   180 {
   181   int i;
   182   int bit = 1 << (n - 1);
   183 
   184   for (i = 0; i < n; i++) {
   185     str[i] = (bits & bit) ? '1' : '0';
   186     bit >>= 1;
   187   }
   188   str[i] = 0;
   189 
   190   return str;
   191 }