[xiph-cvs] cvs commit: w3d coder.c.in rle.h Makefile TODO coder.h main.c tarkin.h wavelet.c wavelet.h coder.c

Holger Waechtler holger at xiph.org
Wed Mar 28 05:47:00 PST 2001



holger      01/03/28 05:47:00

  Modified:    .        Makefile TODO coder.h main.c tarkin.h wavelet.c
                        wavelet.h
  Added:       .        coder.c.in rle.h
  Removed:     .        coder.c
  Log:
  - new coefficient encoder. Still buggy.
  - removed all self-defined int8, int16, etc and use <stdint.h> types instead
    Thanks to Simon for the hint !
  - the skip-empty bitplane logic never worked fine; I removed it. Perhaps it may
    come back later when I have an idea where the real problem was ...
  - the bitplane shift logic has gone and needs to be reintroduced too.

Revision  Changes    Path
1.2       +8 -5      w3d/Makefile

Index: Makefile
===================================================================
RCS file: /usr/local/cvsroot/w3d/Makefile,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Makefile	2001/02/13 00:56:02	1.1
+++ Makefile	2001/03/28 13:46:58	1.2
@@ -1,11 +1,11 @@
 CC = gcc
 RM = rm -rf
 
-CFLAGS = -g -O0 -Wall
+CFLAGS = -g -O0 -Wall -DTYPE=int16_t
 LFLAGS = 
 
-SRCS = coder.c main.c videodev.c wavelet.c yuv.c
-OBJS = $(SRCS:.c=.o)
+OBJS = coder.o main.o wavelet.o yuv.o
+SRCS = $(OBJS:.o=.c)
 TARGET = main
 
 
@@ -14,15 +14,18 @@
 $(TARGET): .depend $(OBJS)
         $(CC) $(LFLAGS) $(OBJS) -o $@
 
+coder.c: coder.c.in rle.h
+	cpp -P $< | indent -i3 -kr -bad > $@
+
 .c.o: .depend
         $(CC) $(CFLAGS) -c $<
 
 clean:
-	$(RM) $(OBJS) $(TARGET) core .depend .depend.bak rle.histogram *.ppm
+	$(RM) $(OBJS) $(TARGET) core .depend .depend.bak rle.histogram *.ppm coder.c
 
 
 .depend: $(SRCS)
         touch .depend
-	makedepend -f.depend -- $(CFLAGS) -- $(SRCS)
+	makedepend -f.depend -- $(CFLAGS) -- $(SRCS) coder.c.in
 
 -include .depend

1.2       +0 -3      w3d/TODO

Index: TODO
===================================================================
RCS file: /usr/local/cvsroot/w3d/TODO,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TODO	2001/02/13 00:56:02	1.1
+++ TODO	2001/03/28 13:46:58	1.2
@@ -1,10 +1,7 @@
- - design file/stream format and find a cool name for this codec
  - write avitow3d/quicktimetow3d/player/recorder (a libsndfile/libaudiofile alike video library would be great !)
- - tune coefficient transmission order in coder.c
  - (4,4) - Wavelets
  - arithmetic binary entropy coders may be faster, simpler and more efficient
  - profile
  - rewrite wavelet xform code, the current implementation forces cache misses
- - skip first empty bitplanes, we could save a per-level min/max value
  - introduce fast paths in coefficient decoder if (mps == 0)
  - mmx/3dnow/sse/altivec

1.2       +5 -24     w3d/coder.h

Index: coder.h
===================================================================
RCS file: /usr/local/cvsroot/w3d/coder.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- coder.h	2001/02/13 00:56:02	1.1
+++ coder.h	2001/03/28 13:46:58	1.2
@@ -3,36 +3,17 @@
 #define __CODER_H
 
 #include <stdlib.h>
-#include "global_defs.h"
+#include <stdint.h>
 #include "wavelet.h"
 
 
-typedef struct {
-   int     bit_count;          /*  number of valid bits in byte    */
-   uint8   byte;               /*  buffer to save bits             */
-   int     byte_count;         /*  number of bytes written         */
-   uint8  *bitstream;
-   size_t  limit;              /*  don't write more bytes to bitstream ... */
-} BitCoderState;
 
+extern size_t encode_coeff3d (Wavelet3DBuf *waveletbuf, uint8_t *bitstream, size_t limit);
+extern void   decode_coeff3d (Wavelet3DBuf *waveletbuf, uint8_t *bitstream, size_t count);
 
-typedef struct {
-   int mps;                    /*  more probable symbol            */
-   int count;                  /*  have seen count+1 mps's         */
-   BitCoderState bitcoder;
-} RLECoderState;
+extern void predict_childs3d (Wavelet3DBuf *waveletbuf);
+extern void update_childs3d (Wavelet3DBuf *waveletbuf);
 
-
-
-typedef struct {
-   Wavelet3DBuf *waveletbuf;
-   RLECoderState  rlecoder;
-} Coder;
-
-
-
-extern size_t encode_coeff3d (Wavelet3DBuf *waveletbuf, uint8 *bitstream, size_t limit);
-extern void   decode_coeff3d (Wavelet3DBuf *waveletbuf, uint8 *bitstream, size_t count);
 
 #endif
 

1.2       +197 -92   w3d/main.c

Index: main.c
===================================================================
RCS file: /usr/local/cvsroot/w3d/main.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- main.c	2001/02/13 00:56:02	1.1
+++ main.c	2001/03/28 13:46:58	1.2
@@ -1,49 +1,134 @@
 
 #include <stdio.h>
-#include "videodev.h"
+#include <stdint.h>
+#include <string.h>
 #include "wavelet.h"
 #include "coder.h"
 #include "yuv.h"
+#include "rle.h"
 
 
-#define  N_FRAMES  4
+#define  N_FRAMES  1
 
 
-void save_ppm (char *prefix, uint8 *buf, int w, int h)
+int read_ppm_info (char *fmt, int *w, int *h)
 {
    int i;
+   char fname [256];
+   FILE *file;
 
-   for (i=0; i<N_FRAMES; i++)
+   sprintf (fname, fmt, 0);
+   file = fopen (fname, "r");
+
+   if (!file) {
+      fprintf(stderr, "Error: opening first frame '%s'\n", fname);
+      return -1;
+   }
+
+   for (i=0; i<3; i++) {
+      char ln [255];
+      fgets(ln, 255, file);
+      if(*ln == '#')
+         i--;
+      else {
+         if (i == 0 && strncmp("P6", ln, 2)) {
+            fprintf(stderr, "Error: Need PPM file for input\n");
+            fclose (file);
+            exit(-1);
+         }
+         if (i == 1) {
+            ln[20] = 0;
+            sscanf(ln, "%i %i", w, h);
+         }
+      }
+   }
+
+   fclose (file);
+   return 0;
+}
+
+
+int read_ppm (char *fmt, int frame, uint8_t *buf, int w, int h)
+{
+   int i;
+   long _w, _h;
+   char fname [256];
+   FILE *file;
+
+   sprintf (fname, fmt, frame);
+   file = fopen (fname, "r");
+
+   if (!file)
+      return -1;
+
+   for (i=0; i<3; i++) {
+      char ln [256];
+
+      fgets(ln, 255, file);
+      if(*ln == '#')
+         i--;
+      else {
+         if (i == 0 && strncmp("P6", ln, 2)) {
+            fprintf(stderr, "Error: Need PPM file for input\n");
+            fclose (file);
+            exit(-1);
+         }
+         if (i == 1) {
+            ln[20] = 0;
+            sscanf(ln, "%ld %ld", &_w, &_h);
+         }
+      }
+   }
+
+   if (w != _w || h != _h) {
+      fprintf (stderr, "%s: image size inconsistent (w: %i <-> %ld, h: %i <-> %ld) !\n", __FUNCTION__, w, _w, h , _h);
+      fclose (file);
+      exit (-1);
+   }
+
+   fread (buf, 3, w*h, file);
+   fclose (file);
+   return 0;
+}
+
+
+void save_ppm (char *fmt, uint8_t *buf, int w, int h, int first_frame, int frames)
+{
+   int i;
+
+   for (i=0; i<frames; i++)
    {
       char fname [256];
       FILE *outfile;
-      uint8 *img = buf + w * h * 3 * i;
+      uint8_t *img = buf + w * h * 3 * i;
 
-      sprintf (fname , "%s%i.ppm", prefix, i);
+      sprintf (fname, fmt, i + first_frame);
       outfile = fopen (fname, "w");
       fprintf (outfile, "P6\n%d %d\n%d\n", w, h, 255);
       fwrite (img, 3, w*h, outfile);
+      fclose (outfile);
    }
 }
 
 
-void save_ppm16 (char *prefix, int16 *buf, int w, int h)
+void save_ppm16 (char *fmt, int16_t *buf, int w, int h, int first_frame, int frames)
 {
    int i, j;
 
-   for (i=0; i<N_FRAMES; i++)
+   for (i=0; i<frames; i++)
    {
       char fname [256];
       FILE *outfile;
-      int16 *img = buf + w * h * i;
+      int16_t *img = buf + w * h * i;
 
-      sprintf (fname , "%s%i.ppm", prefix, i);
+      sprintf (fname, fmt, i + first_frame);
       outfile = fopen (fname, "w");
       fprintf (outfile, "P6\n%d %d\n%d\n", w, h, 255);
       for (j=0; j<w*h; j++) {
-         uint8 c [3] = { img[j], img [j], img[j] };
+         uint8_t c [3] = { img[j], img[j], img[j] };
          fwrite (c, 1, 3, outfile);
       }
+      fclose (outfile);
    }
 }
 
@@ -52,22 +137,21 @@
 
 int main (int argc, char **argv)
 {
-   VideoDev *vdev;
-   char *vdev_name = "/dev/video0";
-   uint8 *rgb, *rgb2;
+   char *fmt = "%i.ppm";
+   uint8_t *rgb, *rgb2;
    char *bitstream [3];
    int i, ycount, ucount, vcount;
    int ylimit, ulimit, vlimit;
-   Wavelet3DBuf *y, *u, *v, *y2, *u2, *v2;
+   int width = -1, height = -1, frames = 0, frame = 0;
 
    if (argc == 5)
-      vdev_name = argv[4];
+      fmt = argv[4];
    else if (argc != 4) {
       printf ("\n"
-        " usage: %s <ylimit> <ulimit> <vlimit> <videodevice>\n"
+        " usage: %s <ylimit> <ulimit> <vlimit> <input filename format string>\n"
         "\n"
-        "   ylimit, ulimit, vlimit: cut Y/U/V bitstream after limit bytes\n"
-        "   videodevice:            optional, /dev/video0 by default\n"
+        "   ylimit, ulimit, vlimit:     cut Y/U/V bitstream after limit bytes/frame\n"
+        "   input ppm filename format:  optional, \"%%i.ppm\" by default\n"
         "\n", argv[0]);
       exit (-1);
    }
@@ -76,102 +160,123 @@
    ulimit = strtol (argv[2], 0, 0);
    vlimit = strtol (argv[3], 0, 0);
 
-   vdev = video_device_new (vdev_name);
-
-   if (!vdev) {
-      printf ("failed opening videodevice.\n");
-      return (-1);
-   }
+   if (read_ppm_info (fmt, &width, &height) < 0)
+      exit (-1);
 
-   rgb  = malloc (vdev->win.width * vdev->win.height * 3 * N_FRAMES);
-   rgb2 = malloc (vdev->win.width * vdev->win.height * 3 * N_FRAMES);
-   bitstream[0] = malloc (vdev->win.width * vdev->win.height * N_FRAMES);
-   bitstream[1] = malloc (vdev->win.width * vdev->win.height * N_FRAMES);
-   bitstream[2] = malloc (vdev->win.width * vdev->win.height * N_FRAMES);
-
-   y = wavelet_3d_buf_new (vdev->win.width, vdev->win.height, N_FRAMES);
-   u = wavelet_3d_buf_new (vdev->win.width, vdev->win.height, N_FRAMES);
-   v = wavelet_3d_buf_new (vdev->win.width, vdev->win.height, N_FRAMES);
-   y2 = wavelet_3d_buf_new (vdev->win.width, vdev->win.height, N_FRAMES);
-   u2 = wavelet_3d_buf_new (vdev->win.width, vdev->win.height, N_FRAMES);
-   v2 = wavelet_3d_buf_new (vdev->win.width, vdev->win.height, N_FRAMES);
+   rgb  = malloc (width * height * 3 * N_FRAMES);
+   rgb2 = malloc (width * height * 3 * N_FRAMES);
+   bitstream[0] = malloc (width * height * N_FRAMES);
+   bitstream[1] = malloc (width * height * N_FRAMES);
+   bitstream[2] = malloc (width * height * N_FRAMES);
 
-   if (!rgb || !rgb2 || !y || !u || !v || !y2 || !u2 || !v2 ||
-       !bitstream[0] || !bitstream[1] || !bitstream[2])
-   {
+   if (!rgb || !rgb2 || !bitstream[0] || !bitstream[1] || !bitstream[2]) {
       printf ("memory allocation failed.\n");
       return (-1);
    }
 
-   video_device_try_palette (vdev, VIDEO_PALETTE_RGB24);
-
-   for (i=0; i<N_FRAMES; i++)
-      video_device_grab_frame (vdev, rgb + vdev->win.width * vdev->win.height * 3 * i);
-
-   save_ppm ("orig", rgb, vdev->win.width, vdev->win.height);
 
-   rgb2yuv (rgb, y->data, u->data, v->data,
-            vdev->win.width * vdev->win.height * N_FRAMES, 3);
+   do {
+      Wavelet3DBuf *y, *u, *v, *y2, *u2, *v2;
 
-   save_ppm16 ("y", y->data, vdev->win.width, vdev->win.height);
-   save_ppm16 ("u", u->data, vdev->win.width, vdev->win.height);
-   save_ppm16 ("v", v->data, vdev->win.width, vdev->win.height);
-
-   wavelet_3d_buf_fwd_xform (y);
-   wavelet_3d_buf_fwd_xform (u);
-   wavelet_3d_buf_fwd_xform (v);
+      for (frames=0; frames<N_FRAMES; frames++) {
+         printf ("read '");
+         printf (fmt, frame + frames);
+         printf ("'");
+         if (read_ppm (fmt, frame + frames,
+                       rgb + width * height * 3 * frames, width, height) < 0)
+         {
+            printf (" failed.\n");
+            break;
+         }
+         printf ("\n");
+      }
 
-   save_ppm16 ("y.coeff", y->data, vdev->win.width, vdev->win.height);
-   save_ppm16 ("u.coeff", u->data, vdev->win.width, vdev->win.height);
-   save_ppm16 ("v.coeff", v->data, vdev->win.width, vdev->win.height);
+      y = wavelet_3d_buf_new (width, height, frames);
+      u = wavelet_3d_buf_new (width, height, frames);
+      v = wavelet_3d_buf_new (width, height, frames);
+      y2 = wavelet_3d_buf_new (width, height, frames);
+      u2 = wavelet_3d_buf_new (width, height, frames);
+      v2 = wavelet_3d_buf_new (width, height, frames);
+
+      if (!y || !u || !v || !y2 || !u2 || !v2) {
+         printf ("memory allocation failed.\n");
+         return (-1);
+      }
 
-   ycount = encode_coeff3d (y, bitstream [0], vdev->win.width * vdev->win.height * N_FRAMES);
-   ucount = encode_coeff3d (u, bitstream [1], vdev->win.width * vdev->win.height * N_FRAMES);
-   vcount = encode_coeff3d (v, bitstream [2], vdev->win.width * vdev->win.height * N_FRAMES);
+      save_ppm ("orig%i.ppm", rgb, width, height, frame, frames);
 
-   if (ycount < ylimit) ylimit = ycount;
-   if (ucount < ulimit) ulimit = ucount;
-   if (vcount < vlimit) vlimit = vcount;
+      rgb2yuv (rgb, y->data, u->data, v->data, width * height * frames, 3);
+/*
+      save_ppm16 ("y%i.ppm", y->data, width, height, frame, frames);
+      save_ppm16 ("u%i.ppm", u->data, width, height, frame, frames);
+      save_ppm16 ("v%i.ppm", v->data, width, height, frame, frames);
+*/
+      wavelet_3d_buf_fwd_xform (y);
+      wavelet_3d_buf_fwd_xform (u);
+      wavelet_3d_buf_fwd_xform (v);
+
+      save_ppm16 ("y.coeff%i.ppm", y->data, width, height, frame, frames);
+      save_ppm16 ("u.coeff%i.ppm", u->data, width, height, frame, frames);
+      save_ppm16 ("v.coeff%i.ppm", v->data, width, height, frame, frames);
+
+      ycount = width * height * frames;
+      ucount = width * height * frames;
+      vcount = width * height * frames;
+
+      if (ycount > frames * ylimit) ycount = frames * ylimit;
+      if (ucount > frames * ulimit) ucount = frames * ulimit;
+      if (vcount > frames * vlimit) vcount = frames * vlimit;
+
+      ycount = encode_coeff3d (y, bitstream [0], ycount);
+      ucount = encode_coeff3d (u, bitstream [1], ucount);
+      vcount = encode_coeff3d (v, bitstream [2], vcount);
+
+      decode_coeff3d (y2, bitstream [0], ycount);
+      decode_coeff3d (u2, bitstream [1], ucount);
+      decode_coeff3d (v2, bitstream [2], vcount);
+
+      for (i=0; i<width*height*frames; i++) {
+         rgb [3*i]   = (y->data[i] == y2->data [i]) ? 0 : ~0;
+         rgb [3*i+1] = (u->data[i] == u2->data [i]) ? 0 : ~0;
+         rgb [3*i+2] = (v->data[i] == v2->data [i]) ? 0 : ~0;
+if (y->data[i] != y2->data [i]) {
+   printf ("%i: %i <-> %i\n", i, y->data[i], y2->data[i]);
+bit_print (y->data[i]);
+bit_print (y2->data[i]);
+}
+      }
 
-   decode_coeff3d (y2, bitstream [0], ylimit);
-   decode_coeff3d (u2, bitstream [1], ulimit);
-   decode_coeff3d (v2, bitstream [2], vlimit);
+      save_ppm ("coeffdiff%i.ppm", rgb, width, height, frame, frames);
 
-   for (i=0; i<vdev->win.width*vdev->win.height*N_FRAMES; i++) {
-      rgb [3*i]   = (y->data[i] == y2->data [i]) ? 0 : ~0;
-      rgb [3*i+1] = (u->data[i] == u2->data [i]) ? 0 : ~0;
-      rgb [3*i+2] = (v->data[i] == v2->data [i]) ? 0 : ~0;
-   }
+      save_ppm16 ("y.rcoeff%i.ppm", y2->data, width, height, frame, frames);
+      save_ppm16 ("u.rcoeff%i.ppm", u2->data, width, height, frame, frames);
+      save_ppm16 ("v.rcoeff%i.ppm", v2->data, width, height, frame, frames);
 
-   save_ppm ("coeffdiff", rgb, vdev->win.width, vdev->win.height);
+      wavelet_3d_buf_inv_xform (y2);
+      wavelet_3d_buf_inv_xform (u2);
+      wavelet_3d_buf_inv_xform (v2);
 
-   save_ppm16 ("y.rcoeff", y2->data, vdev->win.width, vdev->win.height);
-   save_ppm16 ("u.rcoeff", u2->data, vdev->win.width, vdev->win.height);
-   save_ppm16 ("v.rcoeff", v2->data, vdev->win.width, vdev->win.height);
+      save_ppm16 ("yr%i.ppm", y2->data, width, height, frame, frames);
+      save_ppm16 ("ur%i.ppm", u2->data, width, height, frame, frames);
+      save_ppm16 ("vr%i.ppm", v2->data, width, height, frame, frames);
 
-   wavelet_3d_buf_inv_xform (y2);
-   wavelet_3d_buf_inv_xform (u2);
-   wavelet_3d_buf_inv_xform (v2);
+      yuv2rgb (y2->data, u2->data, v2->data, rgb2, width * height * frames, 3);
 
-   save_ppm16 ("yr", y2->data, vdev->win.width, vdev->win.height);
-   save_ppm16 ("ur", u2->data, vdev->win.width, vdev->win.height);
-   save_ppm16 ("vr", v2->data, vdev->win.width, vdev->win.height);
+      save_ppm ("out%03d.ppm", rgb2, width, height, frame, frames);
 
-   yuv2rgb (y2->data, u2->data, v2->data, rgb2,
-            vdev->win.width * vdev->win.height * N_FRAMES, 3);
+      wavelet_3d_buf_destroy (y);
+      wavelet_3d_buf_destroy (u);
+      wavelet_3d_buf_destroy (v);
+      wavelet_3d_buf_destroy (y2);
+      wavelet_3d_buf_destroy (u2);
+      wavelet_3d_buf_destroy (v2);
 
-   save_ppm ("out", rgb2, vdev->win.width, vdev->win.height);
+      frame += frames;
 
-   video_device_destroy (vdev);
+   } while (frames == N_FRAMES);
 
    free (rgb);
    free (rgb2);
-   wavelet_3d_buf_destroy (y);
-   wavelet_3d_buf_destroy (u);
-   wavelet_3d_buf_destroy (v);
-   wavelet_3d_buf_destroy (y2);
-   wavelet_3d_buf_destroy (u2);
-   wavelet_3d_buf_destroy (v2);
    free (bitstream[0]);
    free (bitstream[1]);
    free (bitstream[2]);

1.2       +17 -9     w3d/tarkin.h

Index: tarkin.h
===================================================================
RCS file: /usr/local/cvsroot/w3d/tarkin.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- tarkin.h	2001/02/13 01:00:49	1.1
+++ tarkin.h	2001/03/28 13:46:58	1.2
@@ -1,25 +1,33 @@
 #ifndef __TARKIN_H
 #define __TARKIN_H
 
+typedef enum { TARKIN_RGB, TARKIN_RGBA, TARKIN_GRAYSCALE, TARKIN_ALPHA } VideoChannelType;
 
+
+typedef struct {
+   char *name;
+   VideoChannelType type;
+   uint32 n_component;
+   WaveletBuf3D **waveletbuf [2];
+   uint32 *frames_in_readbuf;
+   uint32 bitrate;
+} TarkinVideoChannel;
+
+
 typedef struct {
    int fd;
    ogg_stream_state os;
-   ogg_page op;
-   WaveletBuf3D *waveletbuf [2];
-   uint32 bitrate;
+   uint32 n_videochannels;
+   TarkinVideoChannel *channel;
 } TarkinStream;
 
 
-TarkinStream* tarkin_read_open (int fd);
-TarkinStream* tarkin_read_open_by_url (char *fname);
+TarkinStream* tarkin_stream_new (int fd);
+void tarkin_stream_destroy (TarkinStream *s);
+
 int tarkin_read_frame (TarkinStream *s, uint8 *buf);
 
-TarkinStream* tarkin_write_open (int fd);
-TarkinStream* tarkin_write_open_by_url (char *fname);
 int tarkin_write_set_bitrate (TarkinStream *s, uint32 bitrate);
 int tarkin_write_frame (TarkinStream *s, uint8 *buf);
-
-void tarkin_close (TarkinStream *s);
 
 #endif

1.2       +55 -45    w3d/wavelet.c

Index: wavelet.c
===================================================================
RCS file: /usr/local/cvsroot/w3d/wavelet.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- wavelet.c	2001/02/13 00:56:02	1.1
+++ wavelet.c	2001/03/28 13:46:58	1.2
@@ -1,14 +1,16 @@
 #include <stdlib.h>
 #include "wavelet.h"
 
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#define MAX3(a,b,c) (MAX(a,MAX(b,c)))
 
 
-Wavelet3DBuf* wavelet_3d_buf_new (uint32 width, uint32 height, uint32 frames)
+Wavelet3DBuf* wavelet_3d_buf_new (uint32_t width, uint32_t height, uint32_t frames)
 {
    Wavelet3DBuf* buf = (Wavelet3DBuf*) malloc (sizeof (Wavelet3DBuf));
-   uint32 _w = width;
-   uint32 _h = height;
-   uint32 _f = frames;
+   uint32_t _w = width;
+   uint32_t _h = height;
+   uint32_t _f = frames;
    int level;
 
    if (!buf)
@@ -33,11 +35,14 @@
       _f = (_f+1)/2;
    }
 
-   buf->w = (uint32*) malloc (buf->scales * sizeof (uint32));
-   buf->h = (uint32*) malloc (buf->scales * sizeof (uint32));
-   buf->f = (uint32*) malloc (buf->scales * sizeof (uint32));
+   buf->w = (uint32_t*) malloc (buf->scales * sizeof (uint32_t));
+   buf->h = (uint32_t*) malloc (buf->scales * sizeof (uint32_t));
+   buf->f = (uint32_t*) malloc (buf->scales * sizeof (uint32_t));
+   buf->offset = (uint32_t (*) [8]) malloc (8 * buf->scales * sizeof (uint32_t));
 
-   if (!buf->w || !buf->h || !buf->f) {
+   buf->scratchbuf = (TYPE*) malloc (MAX3(width, height, frames) * sizeof (TYPE));
+
+   if (!buf->w || !buf->h || !buf->f || !buf->offset || !buf->scratchbuf) {
       wavelet_3d_buf_destroy (buf);
       return NULL;
    }
@@ -50,6 +55,14 @@
       buf->w [level] = (buf->w [level+1] + 1) / 2;
       buf->h [level] = (buf->h [level+1] + 1) / 2;
       buf->f [level] = (buf->f [level+1] + 1) / 2;
+      buf->offset[level][0] = 0;
+      buf->offset[level][1] = buf->w [level];
+      buf->offset[level][2] = buf->h [level] * width;
+      buf->offset[level][3] = buf->f [level] * width * height;
+      buf->offset[level][4] = buf->offset [level][2] + buf->w [level];
+      buf->offset[level][5] = buf->offset [level][3] + buf->w [level];
+      buf->offset[level][6] = buf->offset [level][3] + buf->offset [level][2];
+      buf->offset[level][7] = buf->offset [level][6] + buf->w [level];
    }
 
    return buf;
@@ -60,29 +73,32 @@
 
 void wavelet_3d_buf_destroy (Wavelet3DBuf* buf)
 {
-   if (buf->data)
-      free (buf->data);
-   if (buf->w)
-      free (buf->w);
-   if (buf->h)
-      free (buf->h);
-   if (buf->f)
-      free (buf->f);
-   if (buf)
+   if (buf) {
+      if (buf->data)
+         free (buf->data);
+      if (buf->w)
+         free (buf->w);
+      if (buf->h)
+         free (buf->h);
+      if (buf->f)
+         free (buf->f);
+      if (buf->offset)
+         free (buf->offset);
+      if (buf->scratchbuf)
+         free (buf->scratchbuf);
       free (buf);
+   }
 }
 
 
 
 
-
 static inline
-void __fwd_xform__ (TYPE *data, int stride, int n)
+void __fwd_xform__ (Wavelet3DBuf *buf, TYPE *data, int stride, int n)
 {
-   TYPE *_d = (TYPE*) malloc (sizeof(TYPE) * n/2);
+   TYPE *d = buf->scratchbuf;
    TYPE *x = data;
    TYPE *s = data;
-   TYPE *d = _d;
    int i, k=n/2;
 
    for (i=0; i<((n&1) ? k : (k-1)); i++)   /*  highpass coefficients */
@@ -101,25 +117,21 @@
 
    for (i=0; i<n/2; i++)
       x [(n-k+i)*stride] = d [i];
-
-   free (_d);
 }
 
 
 static inline
-void __inv_xform__ (TYPE *data, int stride, int n)
+void __inv_xform__ (Wavelet3DBuf *buf, TYPE *data, int stride, int n)
 {
    int i, k=n/2;
-   TYPE *_s = (TYPE*) malloc (sizeof(TYPE) * k+1);
-   TYPE *_d = (TYPE*) malloc (sizeof(TYPE) * k);
+   TYPE *s = buf->scratchbuf;
+   TYPE *d = buf->scratchbuf + n - k;
    TYPE *x = data;
-   TYPE *d = _d;
-   TYPE *s = _s;
 
    for (i=0; i<k+1; i++)
       s [i] = x [i*stride];
 
-   for (i=0; i<n-k; i++)
+   for (i=0; i<n/2; i++)
       d [i] = x [(n-k+i)*stride];
 
    x [0] = s[0] - (d[0] >> 1);
@@ -135,9 +147,6 @@
 
    if (!(n & 1))                                /*  n is even   */
       x [(n-1)*stride] = d[k-1] + x[(n-2)*stride];
-
-   free (_s);
-   free (_d);
 }
 
 
@@ -148,17 +157,17 @@
 {
    int level;
 
-   for (level=level=buf->scales-1; level>0; level--) {
-      uint32 w = buf->w[level];
-      uint32 h = buf->h[level];
-      uint32 f = buf->f[level];
+   for (level=buf->scales-1; level>0; level--) {
+      uint32_t w = buf->w[level];
+      uint32_t h = buf->h[level];
+      uint32_t f = buf->f[level];
 
       if (w > 1) {
          int row, frame;
          for (frame=0; frame<f; frame++) {
             for (row=0; row<h; row++) {
                TYPE *data = buf->data + (frame * buf->height + row) * buf->width;
-               __fwd_xform__ (data, 1, w);
+               __fwd_xform__ (buf, data, 1, w);
             }
          }
       }
@@ -168,7 +177,7 @@
          for (frame=0; frame<f; frame++) {
             for (col=0; col<w; col++) {
                TYPE *data = buf->data + frame * buf->width * buf->height + col;
-               __fwd_xform__ (data, buf->width, h);
+               __fwd_xform__ (buf, data, buf->width, h);
             }
          }
       }
@@ -178,7 +187,7 @@
          for (j=0; j<h; j++) {
             for (i=0; i<w; i++) {
                TYPE *data = buf->data + j*buf->width + i;
-               __fwd_xform__ (data, buf->width * buf->height, f);
+               __fwd_xform__ (buf, data, buf->width * buf->height, f);
             }
          }
       }
@@ -193,16 +202,16 @@
    int level;
 
    for (level=1; level<buf->scales; level++) {
-      uint32 w = buf->w[level];
-      uint32 h = buf->h[level];
-      uint32 f = buf->f[level];
+      uint32_t w = buf->w[level];
+      uint32_t h = buf->h[level];
+      uint32_t f = buf->f[level];
 
       if (f > 1) {
          int i, j;
          for (j=0; j<h; j++) {
             for (i=0; i<w; i++) {
                TYPE *data = buf->data + j*buf->width + i;
-               __inv_xform__ (data, buf->width * buf->height, f);
+               __inv_xform__ (buf, data, buf->width * buf->height, f);
             }
          }
       }
@@ -212,7 +221,7 @@
          for (frame=0; frame<f; frame++) {
             for (col=0; col<w; col++) {
                TYPE *data = buf->data + frame * buf->width * buf->height + col;
-               __inv_xform__ (data, buf->width, h);
+               __inv_xform__ (buf, data, buf->width, h);
             }
          }
       }
@@ -222,10 +231,11 @@
          for (frame=0; frame<f; frame++) {
             for (row=0; row<h; row++) {
                TYPE *data = buf->data + (frame * buf->height + row) * buf->width;
-               __inv_xform__ (data, 1, w);
+               __inv_xform__ (buf, data, 1, w);
             }
          }
       }
    }
 }
+
 

1.2       +12 -11    w3d/wavelet.h

Index: wavelet.h
===================================================================
RCS file: /usr/local/cvsroot/w3d/wavelet.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- wavelet.h	2001/02/13 00:56:02	1.1
+++ wavelet.h	2001/03/28 13:46:58	1.2
@@ -1,28 +1,29 @@
 #ifndef __WAVELET_H
 #define __WAVELET_H
 
-#include "global_defs.h"
+#include <stdint.h>
 
 
 typedef struct {
    TYPE *data;
-   uint32 width;
-   uint32 height;
-   uint32 frames;
-   uint32 scales;
-   uint32 *w;
-   uint32 *h;
-   uint32 *f;
+   uint32_t width;
+   uint32_t height;
+   uint32_t frames;
+   uint32_t scales;
+   uint32_t *w;
+   uint32_t *h;
+   uint32_t *f;
+   uint32_t (*offset)[8];
+   TYPE *scratchbuf;
 } Wavelet3DBuf;
 
 
-extern Wavelet3DBuf* wavelet_3d_buf_new (uint32 width, uint32 height,
-                                         uint32 frames);
+extern Wavelet3DBuf* wavelet_3d_buf_new (uint32_t width, uint32_t height,
+                                         uint32_t frames);
 
 extern void wavelet_3d_buf_destroy (Wavelet3DBuf* buf);
 
 extern void wavelet_3d_buf_fwd_xform (Wavelet3DBuf* buf);
 extern void wavelet_3d_buf_inv_xform (Wavelet3DBuf* buf);
-
 
 #endif

1.1                  w3d/coder.c.in

Index: coder.c.in
===================================================================

#include <stdio.h>
#include <stdint.h>
#include "coder.h"
#include "rle.h"

#define OUTPUT_BIT(s,bit)   rlecoder_write_bit(s,bit)
#define INPUT_BIT(s)        rlecoder_read_bit(s)

#define IS_SIGNIFICAND(x)             (mask & ((x >> sign_shift) ^ x))
#define SIGN_SENT_BIT                 (1 << (8*sizeof(TYPE)-2))
#define COEFF_WAS_SIGNIFICAND(coeff)  ((coeff ^ (coeff >> 1)) & SIGN_SENT_BIT)
#define BITPLANE(coeff)               ((x >> (8*sizeof(TYPE)-7)) & 0x1f)
#define CAN_SKIP_COEFF(coeff)         (COEFF_WAS_SIGNIFICAND(coeff) || BITPLANE(coeff) == bitplane)
#define UPDATE_BITPLANE(coeff)        (coeff = (coeff & ~(0x1f << (8*sizeof(TYPE)-7))) | ((bitplane & 0x1f) << (8*sizeof(TYPE)-7)))
#define SIGN(x)                       (((x & (1 << (8*sizeof(TYPE)-1))) >> (8*sizeof(TYPE)-1)))

void clear_masks (Wavelet3DBuf *waveletbuf)
{
   int i;
   for (i=0; i<waveletbuf->width*waveletbuf->height*waveletbuf->frames; i++) {
      if (SIGN(waveletbuf->data[i])) {
         waveletbuf->data[i] |= 0x3f << (8*sizeof(TYPE) - 7);
      } else {
         waveletbuf->data[i] &= ~(0x3f << (8*sizeof(TYPE) - 7));
      }
   }
}

#define WRITE_UNSIGNED_8BIT(x)                         \
   do {                                                \
      int i;                                           \
                                                       \
      for (i=7; i>=0; i--)                             \
         OUTPUT_BIT(&rlecoder,((x) & (1 << i)) >> i);  \
                                                       \
      x ^= SIGN_SENT_BIT;                              \
   } while (0)

/**
 *  write 8 least significand bits and sign of TYPE x
 */
#define WRITE_SIGNED_8BIT(x)                           \
   do {                                                \
      int i;                                           \
                                                       \
      OUTPUT_BIT(&rlecoder,SIGN(x));                   \
      for (i=7; i>=0; i--)                             \
         OUTPUT_BIT(&rlecoder,((x) & (1 << i)) >> i);  \
                                                       \
      x ^= SIGN_SENT_BIT;                              \
   } while (0)

#define ENCODE(quadrant,w0,h0,f0)                                             \
do {                                                                          \
   int x0, y0, z0;                                                            \
                                                                              \
   for (z0=0; z0<f0; z0++) {                                                  \
      for (y0=0; y0<h0; y0++) {                                               \
         for (x0=0; x0<w0; x0++) {                                            \
            uint8_t *path = (uint8_t*) (void*) waveletbuf->scratchbuf;        \
            int32_t childlevel = 0;                                           \
                                                                              \
            path[0] = 0;                                                      \
            do {                                                              \
               uint32_t x = x0 + (path [childlevel] & 1);                     \
               uint32_t y = y0 + ((path [childlevel] >> 1) & 1);              \
               uint32_t z = z0 + ((path [childlevel] >> 2) & 1);              \
                                                                              \
               if (rlecoder.bitcoder.byte_count >= rlecoder.bitcoder.limit) { \
                  clear_masks (waveletbuf);                                   \
                  return  rlecoder_done (&rlecoder);                          \
               }                                                              \
                                                                              \
               if (level+childlevel+1 < waveletbuf->scales                    \
                && x < waveletbuf->w[level+childlevel+1]                      \
                && y < waveletbuf->h[level+childlevel+1]                      \
                && z < waveletbuf->f[level+childlevel+1])                     \
               {                                                              \
                  TYPE *coeff = waveletbuf->data                              \
                        + waveletbuf->offset [level + childlevel] [quadrant]  \
                        + z * waveletbuf->width * waveletbuf->height          \
                        + y * waveletbuf->width + x;                          \
                                                                              \
                  if (COEFF_WAS_SIGNIFICAND(*coeff)) {                        \
                     if (IS_SIGNIFICAND(*coeff)) {                            \
                        OUTPUT_BIT(&rlecoder,1);                              \
                     } else {                                                 \
                        OUTPUT_BIT(&rlecoder,0);                              \
                     }                                                        \
                     UPDATE_BITPLANE(*coeff);                                 \
          /*         path [childlevel]++;                                     \
                     while (path [childlevel] == 8 && childlevel > 0) {       \
                        childlevel--;                                         \
                        path [childlevel]++;                                  \
                        x0 >>= 1;                                             \
                        y0 >>= 1;                                             \
                        z0 >>= 1;                                             \
                     }                                                        \
            */    } else {                                                    \
                     if (IS_SIGNIFICAND(*coeff)) {                            \
                        OUTPUT_BIT(&rlecoder,1);                              \
                        OUTPUT_BIT(&rlecoder,SIGN(*coeff));                   \
                        *coeff ^= SIGN_SENT_BIT;                              \
                        UPDATE_BITPLANE(*coeff);                              \
           /*           x0 = x << 1;                                          \
                        y0 = y << 1;                                          \
                        z0 = z << 1;                                          \
                        childlevel++;                                         \
                        path [childlevel] = 0;                                \
             */      } else {                                                 \
                        OUTPUT_BIT(&rlecoder,0);                              \
                        if (mask == 1) {                                      \
                           OUTPUT_BIT(&rlecoder,SIGN(*coeff));                \
                           *coeff ^= SIGN_SENT_BIT;                           \
                           UPDATE_BITPLANE(*coeff);                           \
                        }                                                     \
            /*          path [childlevel]++;                                  \
                        while (path [childlevel] == 8 && childlevel > 0) {    \
                           childlevel--;                                      \
                           path [childlevel]++;                               \
                           x0 >>= 1;                                          \
                           y0 >>= 1;                                          \
                           z0 >>= 1;                                          \
                        }                                                     \
            */       }                                                        \
                  }                                                           \
               } else {                                                       \
           /*     do {                                                        \
                     childlevel--;                                            \
                     path [childlevel]++;                                     \
                     x0 >>= 1;                                                \
                     y0 >>= 1;                                                \
                     z0 >>= 1;                                                \
                  } while (path [childlevel] == 8 && childlevel > 0);         \
          */   }                                                              \
            } while (childlevel > 0);                                         \
         }                                                                    \
      }                                                                       \
   }                                                                          \
} while (0)

/**
 *  encode waveletbuf until limit bytes are written to
 *  bitstream or complete buffer is encoded.
 *
 */
size_t encode_coeff3d (Wavelet3DBuf *waveletbuf, uint8_t *bitstream, size_t limit)
{
   RLECoderState rlecoder = { -1, 0, { 0, 0, 0, bitstream, limit } };
   int bitplane;
   int  w = waveletbuf->width;
   int  h = waveletbuf->height;
   int  f = waveletbuf->frames;

   WRITE_SIGNED_8BIT(waveletbuf->data[0]);

   for (bitplane=8; bitplane>=0; bitplane--) {
      TYPE mask = 1 << bitplane;
      int sign_shift = 8*sizeof(TYPE) - 1 - bitplane;
      int level;

      for (level=0; level < waveletbuf->scales-1; level++) {
         uint32_t w1, h1, f1;

         if (rlecoder.bitcoder.byte_count >= rlecoder.bitcoder.limit) {
            clear_masks (waveletbuf);
            return  rlecoder_done (&rlecoder);
         }

         w = waveletbuf->w [level];
         h = waveletbuf->h [level];
         f = waveletbuf->f [level];
         w1 = waveletbuf->w [level+1] - w;
         h1 = waveletbuf->h [level+1] - h;
         f1 = waveletbuf->f [level+1] - f;

         if (w1 > 0)  ENCODE (1,w1,h,f);
         if (h1 > 0)  ENCODE (2,w,h1,f);
         if (f1 > 0)  ENCODE (3,w,h,f1);
         if (w1 > 0 && h1 > 0)  ENCODE (4,w1,h1,f);
         if (w1 > 0 && f1 > 0)  ENCODE (5,w,h,f1);
         if (h1 > 0 && f1 > 0)  ENCODE (6,w,h1,f1);
         if (w1 > 0 && h1 > 0 && f1 > 0)  ENCODE (7,w1,h1,f1);
      }
   }

   clear_masks (waveletbuf);
   return  rlecoder_done (&rlecoder);
}

#define READ_UNSIGNED_8BIT(x)                \
   do {                                      \
      int i;                                 \
                                             \
      x = 0;                                 \
      for (i=7; i>=0; i--)                   \
         if (INPUT_BIT(&rlecoder))           \
            x |= 1 << i;                     \
                                             \
      x ^= SIGN_SENT_BIT;                    \
   } while (0)

#define READ_SIGNED_8BIT(x)                  \
   do {                                      \
      int i;                                 \
                                             \
      x = INPUT_BIT(&rlecoder) ? ~0xff : 0;  \
      for (i=7; i>=0; i--)                   \
         if (INPUT_BIT(&rlecoder))           \
            x |= 1 << i;                     \
                                             \
      x ^= SIGN_SENT_BIT;                    \
   } while (0)

#define DECODE(quadrant,w0,h0,f0)                                             \
do {                                                                          \
   int x0, y0, z0;                                                            \
                                                                              \
   for (z0=0; z0<f0; z0++) {                                                  \
      for (y0=0; y0<h0; y0++) {                                               \
         for (x0=0; x0<w0; x0++) {                                            \
            uint8_t *path = (uint8_t*) (void*) waveletbuf->scratchbuf;        \
            int32_t childlevel = 0;                                           \
                                                                              \
            path[0] = 0;                                                      \
            do {                                                              \
               uint32_t x = x0 + (path [childlevel] & 1);                     \
               uint32_t y = y0 + ((path [childlevel] >> 1) & 1);              \
               uint32_t z = z0 + ((path [childlevel] >> 2) & 1);              \
                                                                              \
               if (rlecoder.bitcoder.byte_count >= rlecoder.bitcoder.limit) { \
                  clear_masks (waveletbuf);                                   \
                  return;                                                     \
               }                                                              \
                                                                              \
               if (level+childlevel+1 < waveletbuf->scales                    \
                && x < waveletbuf->w [level+childlevel+1]                     \
                && y < waveletbuf->h [level+childlevel+1]                     \
                && z < waveletbuf->f [level+childlevel+1])                    \
               {                                                              \
                  TYPE *coeff = waveletbuf->data                              \
                        + waveletbuf->offset [level + childlevel] [quadrant]  \
                        + z * waveletbuf->width * waveletbuf->height          \
                        + y * waveletbuf->width + x;                          \
                                                                              \
                  if (COEFF_WAS_SIGNIFICAND(*coeff)) {                        \
                     if (INPUT_BIT(&rlecoder))                                \
                        *coeff ^= mask /*| (mask >> 1)*/;                     \
                     UPDATE_BITPLANE(*coeff);                                 \
         /*          path [childlevel]++;                                     \
                     while (path [childlevel] == 8 && childlevel > 0) {       \
                        childlevel--;                                         \
                        path [childlevel]++;                                  \
                        x0 >>= 1;                                             \
                        y0 >>= 1;                                             \
                        z0 >>= 1;                                             \
                     }                                                        \
         */       } else {                                                    \
                     if (INPUT_BIT(&rlecoder)) {                              \
                        if (INPUT_BIT(&rlecoder))                             \
                           *coeff = ~0;                                       \
                        *coeff ^= mask /*| (mask >> 1)*/;                     \
                        *coeff ^= SIGN_SENT_BIT;                              \
                        UPDATE_BITPLANE(*coeff);                              \
      /*                x0 = x << 1;                                          \
                        y0 = y << 1;                                          \
                        z0 = z << 1;                                          \
                        childlevel++;                                         \
                        path [childlevel] = 0;                                \
        */           } else {                                                 \
                        if (mask == 1) {                                      \
                           if (INPUT_BIT(&rlecoder))                          \
                              *coeff = ~0;                                    \
                           *coeff ^= SIGN_SENT_BIT;                           \
                           UPDATE_BITPLANE(*coeff);                           \
                        }                                                     \
          /*            path [childlevel]++;                                  \
                        while (path [childlevel] == 8 && childlevel > 0) {    \
                           childlevel--;                                      \
                           path [childlevel]++;                               \
                           x0 >>= 1;                                          \
                           y0 >>= 1;                                          \
                           z0 >>= 1;                                          \
                        }                                                     \
            */       }                                                        \
                  }                                                           \
               } else {                                                       \
       /*         do {                                                        \
                     childlevel--;                                            \
                     path [childlevel]++;                                     \
                     x0 >>= 1;                                                \
                     y0 >>= 1;                                                \
                     z0 >>= 1;                                                \
                  } while (path [childlevel] == 8 && childlevel > 0);         \
         */    }                                                              \
            } while (childlevel > 0);                                         \
         }                                                                    \
      }                                                                       \
   }                                                                          \
} while (0)

/**
 *  decode count bytes from bitstream to waveletbuf.
 *
 */
void decode_coeff3d (Wavelet3DBuf *waveletbuf, uint8_t *bitstream, size_t count)
{
   RLECoderState rlecoder = { -1, 0, { 0, 0, 0, bitstream, count } };
   int bitplane;
   int w = waveletbuf->width;
   int h = waveletbuf->height;
   int f = waveletbuf->frames;

   memset (waveletbuf->data, 0, w * h * f * sizeof(TYPE));

   READ_SIGNED_8BIT(waveletbuf->data[0]);

   for (bitplane=8; bitplane>=0; bitplane--) {
      int level;

      for (level=0; level < waveletbuf->scales-1; level++) {
         uint32_t w1, h1, f1;
         TYPE mask = 1 << bitplane;

         if (rlecoder.bitcoder.byte_count >= rlecoder.bitcoder.limit) {
            clear_masks (waveletbuf);
            return;
         }

         w = waveletbuf->w [level];
         h = waveletbuf->h [level];
         f = waveletbuf->f [level];
         w1 = waveletbuf->w [level+1] - w;
         h1 = waveletbuf->h [level+1] - h;
         f1 = waveletbuf->f [level+1] - f;

         if (w1 > 0)  DECODE (1,w1,h,f);
         if (h1 > 0)  DECODE (2,w,h1,f);
         if (f1 > 0)  DECODE (3,w,h,f1);
         if (w1 > 0 && h1 > 0)  DECODE (4,w1,h1,f);
         if (w1 > 0 && f1 > 0)  DECODE (5,w,h,f1);
         if (h1 > 0 && f1 > 0)  DECODE (6,w,h1,f1);
         if (w1 > 0 && h1 > 0 && f1 > 0)  DECODE (7,w1,h1,f1);
      }
   }
   clear_masks (waveletbuf);
}

1.1                  w3d/rle.h

Index: rle.h
===================================================================
#ifndef __RLE_H
#define __RLE_H

#include <stdio.h>
#include <stdint.h>

#define RLE_HISTOGRAM 1

typedef struct {
   int       bit_count;          /*  number of valid bits in byte    */
   uint8_t   byte;               /*  buffer to save bits             */
   int       byte_count;         /*  number of bytes written         */
   uint8_t  *bitstream;
   size_t    limit;              /*  don't write more bytes to bitstream ... */
} BitCoderState;

typedef struct {
   int mps;                    /*  more probable symbol            */
   int count;                  /*  have seen count+1 mps's         */
   BitCoderState bitcoder;
} RLECoderState;

static inline
void bitcoder_write_bit (BitCoderState *s, int bit)
{ 
   s->byte <<= 1;

   if (bit)
      s->byte |= 1;

   s->bit_count++;
   if (s->bit_count == 8 && s->byte_count < s->limit) {
      s->bitstream [s->byte_count++] = s->byte;
      s->bit_count = 0;
   }
}

static inline
int bitcoder_read_bit (BitCoderState *s)
{
   int ret;

   if (s->bit_count == 0 && s->byte_count < s->limit) {
      s->byte = s->bitstream [s->byte_count++];
      s->bit_count = 8;
   }

   ret = (s->byte & 0x80) >> 7;
   s->byte <<= 1; 
   s->bit_count--;

   return ret;
}

static inline
size_t bitcoder_flush (BitCoderState *s)
{
   if (s->bit_count > 0 && s->byte_count < s->limit)
      s->bitstream [s->byte_count++] = s->byte;

printf ("%s: %i bytes written.\n", __FUNCTION__, s->byte_count);
   return s->byte_count;
}

/*
 *   Ugly.
 */
static inline
uint32_t huffmancoder_read (BitCoderState *s)
{
   if (bitcoder_read_bit (s) == 0)
      return 0;

   if (bitcoder_read_bit (s) == 0)
      return 1;

   if (bitcoder_read_bit (s) == 0) {
      if (bitcoder_read_bit (s) == 0)
         return 2;
      else
         return 3;
   }

   if (bitcoder_read_bit (s) == 0) {
      if (bitcoder_read_bit (s) == 0)
         return 4;
      else
         return 5;
   }

   if (bitcoder_read_bit (s) == 0) {           /* read 8 bit number */
      uint32_t x = 0;
      int i;
      for (i=7; i>=0; i--)
         if (bitcoder_read_bit (s))
            x |= 1 << i;

      return (x + 5);
   } else {                                    /*  read 32 bit number  */
      uint32_t x = 0;
      int i;
      for (i=31; i>=0; i--)
         if (bitcoder_read_bit (s))
            x |= 1 << i;

      return (x + 0xff + 5);
   }
}

/*
 *   special handling if (x > 2^32 - 2)  ???
 */
static inline
void huffmancoder_write (BitCoderState *s, uint32_t x)
{
   if (x == 0) {
      bitcoder_write_bit (s, 0);
      return;
   }

   bitcoder_write_bit (s, 1);
   if (x == 1) {
      bitcoder_write_bit (s, 0);
      return;
   }

   bitcoder_write_bit (s, 1);
   if (x <= 3) {
      bitcoder_write_bit (s, 0);
      if (x == 2) bitcoder_write_bit (s, 0);
      else        bitcoder_write_bit (s, 1);
      return;
   }
   
   bitcoder_write_bit (s, 1);
   if (x <= 5) {
      bitcoder_write_bit (s, 0);
      if (x == 4) bitcoder_write_bit (s, 0);
      else        bitcoder_write_bit (s, 1);
      return;
   }

   x -= 5;
   bitcoder_write_bit (s, 1);
   if (x <= 0xff) {
      int i;
      bitcoder_write_bit (s, 0);
      for (i=7; i>=0; i--)
         bitcoder_write_bit (s, x & (1 << i));
   } else {
      int i;
      x -= 0xff;
      bitcoder_write_bit (s, 1);
      for (i=31; i>=0; i--)
         bitcoder_write_bit (s, x & (1 << i));
   }
}

#ifdef RLE_HISTOGRAM
uint32_t histogram [512];
uint32_t max_runlength;
#endif

/*
 *   bit should be 0 or 1 !!!
 */
static inline
void rlecoder_write_bit (RLECoderState *s, int bit)
{
   if (s->mps == -1) {
#ifdef RLE_HISTOGRAM
      memset (histogram, 0, 512*sizeof(uint32_t));
      max_runlength = 0;
#endif
      s->mps = bit ? 1 : 0;
      s->count = 0;
      huffmancoder_write (&s->bitcoder, bit ? 1 : 0);
   }

   if ((bit & 1) == s->mps) 
      s->count++;
   else {

#ifdef RLE_HISTOGRAM
      if (s->count < 511)
         histogram [s->count-1]++;
      else
         histogram [511]++;
      if (max_runlength < s->count)
         max_runlength = s->count-1;
#endif

      huffmancoder_write (&s->bitcoder, s->count-1);
      s->mps = ~s->mps & 1;
      s->count = 1;
   }
}

static inline
int rlecoder_read_bit (RLECoderState *s)
{
   if (s->mps == -1) {
      s->mps = huffmancoder_read (&s->bitcoder);
      s->count = huffmancoder_read (&s->bitcoder) + 1;
   }

   if (s->count == 0) {
      s->count = huffmancoder_read (&s->bitcoder) + 1;
      s->mps = ~s->mps & 1;
   }
   s->count--;

   return (s->mps);
}

/*
 *  returns the number of valid bytes in 
 */
static inline
size_t rlecoder_done (RLECoderState *s)
{
#ifdef RLE_HISTOGRAM
   FILE *f = fopen ("rle.histogram", "w");
   int i;

   fprintf (f, "# max. runlength: %u\n", max_runlength);
   for (i=0; i<512; i++)
      fprintf (f, "%i %u\n", i, histogram[i]);
   fclose (f);
#endif

   return bitcoder_flush (&s->bitcoder);
}

static inline
void bit_print (TYPE byte)
{
   int bit = 8*sizeof(TYPE);

   do {
      bit--;
      printf ((byte & (1 << bit)) ? "1" : "0");
   } while (bit);
   printf ("\n");
}

#endif

--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list