[xiph-cvs] cvs commit: w3d ppm.c ppm.h tarkin-io.c tarkin-io.h tarkin_dec.c tarkin_enc.c Makefile TODO bitcoder.h rle.h tarkin.c tarkin.h wavelet.c yuv.c yuv.h main.c

Holger Waechtler holger at xiph.org
Fri Jun 29 02:19:28 PDT 2001



holger      01/06/29 02:19:27

  Modified:    .        Makefile TODO bitcoder.h rle.h tarkin.c tarkin.h
                        wavelet.c yuv.c yuv.h
  Added:       .        ppm.c ppm.h tarkin-io.c tarkin-io.h tarkin_dec.c
                        tarkin_enc.c
  Removed:     .        main.c
  Log:
   - designed a something-like-a-fileformat; still has to be oggetized
      (file i/o is in tarkin-io.[hc], this is the place to work on this ...)
   - tarkin_enc.c / tarkin_dec.c encode/decode now the tarkin stream
   - removed main.c
   - ppm stuff is now in a ppm.[hc]

Revision  Changes    Path
1.4       +12 -7     w3d/Makefile

Index: Makefile
===================================================================
RCS file: /usr/local/cvsroot/w3d/Makefile,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Makefile	2001/06/25 07:56:07	1.3
+++ Makefile	2001/06/29 09:19:25	1.4
@@ -4,18 +4,22 @@
 CFLAGS = -g -O0 -Wall -DTYPE=int16_t -DRLECODER
 LFLAGS = -g
 
-OBJS = wavelet.o wavelet_xform.o yuv.o tarkin.o main.o
-SRCS = $(OBJS:.o=.c)
+OBJS = ppm.o wavelet.o wavelet_xform.o yuv.o tarkin.o tarkin-io.o
+
 TEST_TARGETS = _test_bitcoder _test_rle _test_huffman
+
+SRCS = $(OBJS:.o=.c)
 TEST_OBJS = $(TEST_TARGETS:=.o)
 TEST_SRCS = $(TEST_OBJS:.o=.c)
-TARGET = main
 
+
+all: tarkin_enc tarkin_dec
 
-all: $(TARGET)
+tarkin_enc: $(OBJS) tarkin_enc.o
+	$(CC) $(LFLAGS) $(OBJS) tarkin_enc.o -o $@
 
-$(TARGET): $(OBJS)
-	$(CC) $(LFLAGS) $(OBJS) -o $@
+tarkin_dec: $(OBJS) tarkin_dec.o
+	$(CC) $(LFLAGS) $(OBJS) tarkin_dec.o -o $@
 
 .c.o: .depend
         $(CC) $(CFLAGS) -c $<
@@ -23,6 +27,7 @@
 clean:
         $(RM) $(OBJS) $(TARGET) gmon.out core .depend .depend.bak rle.histogram *.ppm
         $(RM) $(TEST_TARGETS) $(TEST_OBJS)
+	$(RM) tarkin_enc tarkin_dec tarkin_enc.o tarkin_dec.o
 
 
 test: .depend $(TEST_TARGETS)
@@ -34,6 +39,6 @@
 .depend: $(SRCS) $(TEST_SRCS)
         $(RM) .depend
         touch .depend
-	sh makedepend -f.depend -- $(CFLAGS) -- $(SRCS) $(TEST_SRCS)
+	sh makedepend -f.depend -- $(CFLAGS) -- $(SRCS) $(TEST_SRCS) tarkin_enc.c tarkin_dec.c
 
 -include .depend

1.4       +3 -1      w3d/TODO

Index: TODO
===================================================================
RCS file: /usr/local/cvsroot/w3d/TODO,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- TODO	2001/06/25 07:56:07	1.3
+++ TODO	2001/06/29 09:19:25	1.4
@@ -1,8 +1,10 @@
+- segfaults while destroying encoder stream
+
 Here only the wavelet-related TODO's:
 
  - arithmetic binary entropy coders may be faster, simpler and more efficient;
     implement the ZP-Coder
- - design/implement a stream format
+ - oggetize the stream format
  - write avitotarkin/quicktimetotarkin/mpegtotarkin/player/recorder
     (a libsndfile/libaudiofile alike video library would be great !)
  - profile

1.2       +2 -1      w3d/bitcoder.h

Index: bitcoder.h
===================================================================
RCS file: /usr/local/cvsroot/w3d/bitcoder.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- bitcoder.h	2001/06/25 07:57:09	1.1
+++ bitcoder.h	2001/06/29 09:19:25	1.2
@@ -49,7 +49,8 @@
 static inline
 void bitcoder_encoder_done (BitCoderState *s)
 {
-   free (s->bitstream);
+//  XXX FIXME !!!
+//   free (s->bitstream);
 }
 
 

1.3       +1 -0      w3d/rle.h

Index: rle.h
===================================================================
RCS file: /usr/local/cvsroot/w3d/rle.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- rle.h	2001/06/25 07:56:07	1.2
+++ rle.h	2001/06/29 09:19:25	1.3
@@ -1,6 +1,7 @@
 #ifndef __RLE_H
 #define __RLE_H
 
+#include <string.h>
 #include "bitcoder.h"
 
 #if defined(RLECODER)

1.2       +238 -72   w3d/tarkin.c

Index: tarkin.c
===================================================================
RCS file: /usr/local/cvsroot/w3d/tarkin.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- tarkin.c	2001/06/25 07:56:07	1.1
+++ tarkin.c	2001/06/29 09:19:25	1.2
@@ -1,128 +1,294 @@
-/**
- *   Not yet working.
- *
- *   Everything here should get oggetized. But for now I don't
- *   want to struggle with packets, so I simply write everything 
- *   binary.
+/*
+ *   The real io-stuff is in tarkin-io.c
+ *   (this one has to be rewritten to write ogg streams ...)
  */
 
 #include <stdlib.h>
-#include <unistd.h>
-#include <ctype.h>
 #include <string.h>
 
 #include "tarkin.h"
+#include "tarkin-io.h"
+#include "yuv.h"
 
 
+#define N_FRAMES 1
 
 
-#if __BYTE_ORDER == __LITTLE_ENDIAN
 
-#define LE32_TO_CPU(x)
-#define CPU_TO_LE32(x)
+TarkinStream* tarkin_stream_new (int fd)
+{
+   TarkinStream *s = (TarkinStream*) calloc (1, sizeof(TarkinStream));
 
-#elif __BYTE_ORDER == __BIG_ENDIAN
+   if (!s)
+      return NULL;
 
-#define LE32_TO_CPU(x) x = (((x & 0x000000ff) << 24) | ((x & 0x0000ff00) << 8) \
-                          | ((x & 0x00ff0000) >> 8)  | ((x & 0xff000000) << 24))
-#define CPU_TO_LE32(x) x = (((x & 0x000000ff) << 24) | ((x & 0x0000ff00) << 8) \
-                          | ((x & 0x00ff0000) >> 8)  | ((x & 0xff000000) << 24))
+   s->fd = fd;
+   s->frames_per_buf = N_FRAMES;
 
-#else
-#error  unknown endianess !!
-#endif
+   return s;
+}
 
 
-static
-int read_tarkin_header (int fd, TarkinStream *s)
+void tarkin_stream_destroy (TarkinStream *s)
 {
-   char signature [6];
+   uint32_t i, j;
 
-   if (read (fd, signature, 6) < 6)
-      return TARKIN_IO_ERROR;
+   if (!s)
+      return;
 
-   if (!strncmp(signature, "tarkin", 6) == 0)
-      return TARKIN_SIGNATURE_NOT_FOUND;
+   for (i=0; i<s->n_layers; i++)
+      if (s->layer[i].waveletbuf)
+         for (j=0; j<s->layer[i].n_comp; j++)
+            wavelet_3d_buf_destroy (s->layer[i].waveletbuf[j]);
 
-   if (read (fd, &s->n_layers, 4) < 4)
-      return TARKIN_IO_ERROR;
+   if (s->layer)
+      free(s->layer);
 
-   LE32_TO_CPU(s->n_layers);
+/**
+ *   XXX FIXME HACK Alert: segfault when doin' this right ...
+ *                         somewhere is something really wrong ...
+ *                         perhaps in merge_bitstreams() ???
+ */
+//   if (s->bitstream);
+//      free(s->bitstream);
 
-   return 0;
+   free(s);
 }
 
+
 
-static
-int read_layer_descs (int fd, TarkinStream *s)
+int tarkin_stream_write_layer_descs (TarkinStream *s,
+                                     uint32_t n_layers,
+                                     TarkinVideoLayerDesc desc [])
 {
-   int i;
+   TarkinError err;
+   uint32_t max_bitstream_len = 0;
+   uint32_t i, j;
+
+   s->n_layers = n_layers;
+   s->layer = (TarkinVideoLayer*) calloc (n_layers, sizeof(TarkinVideoLayer));
+
+   for (i=0; i<n_layers; i++) {
+      TarkinVideoLayer *layer = &s->layer[i];
+
+      memcpy (&layer->desc, &desc[i], sizeof(TarkinVideoLayerDesc));
+
+      switch (layer->desc.format) {
+      case TARKIN_GRAYSCALE:
+         layer->n_comp = 1;
+         layer->color_fwd_xform = grayscale_to_y;
+         layer->color_inv_xform = y_to_grayscale;
+         break;
+      case TARKIN_RGB24:
+         layer->n_comp = 3;
+         layer->color_fwd_xform = rgb24_to_yuv;
+         layer->color_inv_xform = yuv_to_rgb24;
+         break;
+      case TARKIN_RGB32:
+         layer->n_comp = 3;
+         layer->color_fwd_xform = rgb32_to_yuv;
+         layer->color_inv_xform = yuv_to_rgb32;
+         break;
+      case TARKIN_RGBA:
+         layer->n_comp = 4;
+         layer->color_fwd_xform = rgba_to_yuv;
+         layer->color_inv_xform = yuv_to_rgba;
+         break;
+      default:
+         BUG("unknown color format");
+         break;
+      };
+
+      layer->waveletbuf = (Wavelet3DBuf**) calloc (layer->n_comp,
+                                                   sizeof(Wavelet3DBuf*));
+      for (j=0; j<layer->n_comp; j++)
+         layer->waveletbuf[j] = wavelet_3d_buf_new (desc[i].width,
+                                                    desc[i].height,
+                                                    desc[i].frames_per_buf);
 
-   s->layer = (TarkinVideoLayer*) calloc (1, s->n_layers * sizeof(TarkinVideoLayer));
+      layer->bitstream_len = layer->desc.bitrate / (8 * layer->n_comp);
 
-   for (i=0; i<s->n_layers; i++) {
-      if (read (fd, &s->layer[i], sizeof(TarkinVideoLayer)) < sizeof(TarkinVideoLayer)) {
-         tarkin_stream_destroy (s);
-         return TARKIN_IO_ERROR;
-      }
-      LE32_TO_CPU(s->layer[i].width);
-      LE32_TO_CPU(s->layer[i].height);
-      LE32_TO_CPU(s->layer[i].frames_per_buf);
-      LE32_TO_CPU(s->layer[i].bitrate);
-      LE32_TO_CPU(s->layer[i].format);
+      if (layer->bitstream_len > max_bitstream_len)
+         max_bitstream_len = layer->bitstream_len;
+
    }
 
-   return 0;
+   if ((err = write_tarkin_header(s->fd, s)) != TARKIN_OK)
+      return err;
+
+   err = write_layer_descs(s->fd, s);
+
+   s->bitstream = (uint8_t*) malloc (max_bitstream_len);
+
+   return err;
 }
 
 
-TarkinStream* tarkin_stream_new (int fd)
+void tarkin_stream_flush (TarkinStream *s)
 {
-   TarkinStream *s = (TarkinStream*) calloc (1, sizeof(TarkinStream));
+   uint32_t i, j;
 
-   if (!s)
-      return NULL;
+   s->current_frame_in_buf=0;
 
-   s->fd = fd;
+   for (i=0; i<s->n_layers; i++) {
+      TarkinVideoLayer *layer = &s->layer[i];
 
-   return s;
+      for (j=0; j<layer->n_comp; j++) {
+         uint32_t bitstream_len;
+
+         wavelet_3d_buf_fwd_xform (layer->waveletbuf[j], 2, 2);
+         bitstream_len = wavelet_3d_buf_encode_coeff (layer->waveletbuf[j],
+                                                      s->bitstream,
+                                                      layer->desc.bitrate/8);
+         write_tarkin_bitstream (s->fd, s->bitstream, bitstream_len);
+      }
+   }
 }
 
 
-void tarkin_stream_destroy (TarkinStream *s)
+uint32_t tarkin_stream_write_frame (TarkinStream *s, uint8_t **rgba)
 {
-   int i;
+   uint32_t i;
 
-   if (!s)
-      return;
+   for (i=0; i<s->n_layers; i++) {
+      TarkinVideoLayer *layer = &s->layer[i];
 
-   for (i=0; i<s->n_layers; i++)
-      if (s->layer[i].waveletbuf)
-         wavelet_3d_buf_destroy (s->layer[i].waveletbuf);
+      layer->color_fwd_xform (rgba[i], layer->waveletbuf,
+                              s->current_frame_in_buf);
+   }
 
-   free(s->layer);
-   free(s);
+   s->current_frame_in_buf++;
+
+   if (s->current_frame_in_buf == s->frames_per_buf)
+      tarkin_stream_flush (s);
+
+   return (++s->current_frame);
 }
 
 
-uint32_t tarkin_read_frame (TarkinStream *s, uint8_t *buf)
+
+
+/**
+ *   return value: number of layers, 0 on i/o error
+ */
+uint32_t tarkin_stream_read_header (TarkinStream *s)
 {
-   if (s->n_layers == 0) {
-      if (read_tarkin_header(s->fd, s) != 0) {
-         tarkin_stream_destroy (s);
-         return 0;
-      }
+   uint32_t max_bitstream_len = 0;
+   uint32_t i, j;
+
+   if (read_tarkin_header(s->fd, s) != TARKIN_OK)
+      return 0;
+
+   if (read_layer_descs(s->fd, s) != TARKIN_OK)
+      return 0;
+
+   for (i=0; i<s->n_layers; i++) {
+      TarkinVideoLayer *layer = &s->layer[i];
+
+      if (layer->desc.format != TARKIN_RGB24)
+         exit (-1);
 
-      if (read_layer_descs(s->fd, s) != 0) {
-         tarkin_stream_destroy (s);
-         return 0;
+      switch (layer->desc.format) {
+      case TARKIN_GRAYSCALE:
+         layer->n_comp = 1;
+         layer->color_fwd_xform = grayscale_to_y;
+         layer->color_inv_xform = y_to_grayscale;
+         break;
+      case TARKIN_RGB24:
+         layer->n_comp = 3;
+         layer->color_fwd_xform = rgb24_to_yuv;
+         layer->color_inv_xform = yuv_to_rgb24;
+         break;
+      case TARKIN_RGB32:
+         layer->n_comp = 3;
+         layer->color_fwd_xform = rgb32_to_yuv;
+         layer->color_inv_xform = yuv_to_rgb32;
+         break;
+      case TARKIN_RGBA:
+         layer->n_comp = 4;
+         layer->color_fwd_xform = rgba_to_yuv;
+         layer->color_inv_xform = yuv_to_rgba;
+         break;
+      default:
+         BUG("unknown color format");
+      };
+
+      layer->waveletbuf = (Wavelet3DBuf**) calloc (layer->n_comp,
+                                                   sizeof(Wavelet3DBuf*));
+      for (j=0; j<layer->n_comp; j++) {
+         layer->waveletbuf[j] = wavelet_3d_buf_new (layer->desc.width,
+                                                    layer->desc.height,
+                                                    layer->desc.frames_per_buf);
+         if (!layer->waveletbuf[j])
+            return 0;
       }
+
+      layer->bitstream_len = layer->desc.bitrate / (8 * layer->n_comp);
+
+      if (layer->bitstream_len > max_bitstream_len)
+         max_bitstream_len = layer->bitstream_len;
    }
-return 0;
+
+   s->bitstream = (uint8_t*) malloc (max_bitstream_len);
+
+   return s->n_layers;
 }
 
 
-uint32_t tarkin_write_set_bitrate (TarkinStream *s, uint32_t bitrate);
-uint32_t tarkin_write_frame (TarkinStream *s, uint8_t *buf);
+
+int tarkin_stream_get_layer_desc (TarkinStream *s,
+                                  uint32_t layer_id,
+                                  TarkinVideoLayerDesc *desc)
+{
+   if (layer_id > s->n_layers-1)
+      return -1;
+
+   memcpy (desc, &(s->layer[layer_id].desc), sizeof(TarkinVideoLayerDesc));
+
+   return 0;
+}
+
+
+/**
+ *   read all layers of the next frame to buf[0..n_layers]
+ *   returns the number of this frame on success, -1 on error
+ */
+uint32_t tarkin_stream_read_frame (TarkinStream *s, uint8_t **rgba)
+{
+   uint32_t i, j;
+
+   if (s->current_frame_in_buf == 0) {
+      for (i=0; i<s->n_layers; i++) {
+         TarkinVideoLayer *layer = &s->layer[i];
+
+         for (j=0; j<layer->n_comp; j++) {
+            uint32_t bitstream_len;
+
+            bitstream_len = read_tarkin_bitstream (s->fd, s->bitstream);
+
+            if (bitstream_len == 0)
+               return 0xffffffff;
+
+            wavelet_3d_buf_decode_coeff (layer->waveletbuf[j], s->bitstream,
+                                         bitstream_len);
+            wavelet_3d_buf_inv_xform (layer->waveletbuf[j], 2, 2);
+         }
+      }
+   }
+
+   for (i=0; i<s->n_layers; i++) {
+      TarkinVideoLayer *layer = &s->layer[i];
+
+      layer->color_inv_xform (layer->waveletbuf, rgba[i],
+                              s->current_frame_in_buf);
+   }
+
+   s->current_frame_in_buf++;
+
+   if (s->current_frame_in_buf == s->frames_per_buf)
+      s->current_frame_in_buf=0;
+
+   return (++s->current_frame);
+}
 
 

1.4       +38 -12    w3d/tarkin.h

Index: tarkin.h
===================================================================
RCS file: /usr/local/cvsroot/w3d/tarkin.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- tarkin.h	2001/06/25 07:56:07	1.3
+++ tarkin.h	2001/06/29 09:19:25	1.4
@@ -1,15 +1,25 @@
 #ifndef __TARKIN_H
 #define __TARKIN_H
 
+#include <stdio.h>
 #include "wavelet.h"
 
+
+#define BUG(x...)                                                            \
+   do {                                                                      \
+      printf("BUG in %s (%s: line %i): ", __FUNCTION__, __FILE__, __LINE__); \
+      printf(#x);                                                            \
+      printf("\n");                                                          \
+      exit (-1);                                                             \
+   } while (0);
+
+
+
 typedef enum {
    TARKIN_GRAYSCALE,
    TARKIN_RGB24,       /*  tight packed RGB        */
    TARKIN_RGB32,       /*  32bit, no alphachannel  */
    TARKIN_RGBA,        /*  dito w/ alphachannel    */
-   TARKIN_ARGB,
-   TARKIN_BGRA
 } TarkinColorFormat;
 
 typedef enum {
@@ -23,15 +33,21 @@
    uint32_t width;
    uint32_t height;
    uint32_t frames_per_buf;
-   uint32_t bitrate;
+   uint32_t bitrate;                    /*  per color component */
    TarkinColorFormat format;
 } TarkinVideoLayerDesc;
 
 
 typedef struct {
    TarkinVideoLayerDesc desc;
-   Wavelet3DBuf *waveletbuf;
-   uint32_t frames_in_readbuf;
+   uint32_t n_comp;                     /*  number of color components */
+   Wavelet3DBuf **waveletbuf;
+   uint32_t current_frame_in_buf;
+
+   uint32_t bitstream_len;
+
+   void (*color_fwd_xform) (uint8_t *rgba, Wavelet3DBuf *yuva [], uint32_t count);
+   void (*color_inv_xform) (Wavelet3DBuf *yuva [], uint8_t *rgba, uint32_t count);
 } TarkinVideoLayer;
 
 
@@ -39,17 +55,27 @@
    int fd;
    uint32_t n_layers;
    TarkinVideoLayer *layer;
+   uint32_t current_frame;
+   uint32_t current_frame_in_buf;
+   uint32_t frames_per_buf;
+   uint8_t *bitstream;
 } TarkinStream;
 
-
-TarkinStream* tarkin_stream_new (int fd);
-void tarkin_stream_destroy (TarkinStream *s);
 
-uint32_t tarkin_read_frame (TarkinStream *s, uint8_t *buf);
+extern TarkinStream* tarkin_stream_new (int fd);
+extern void tarkin_stream_destroy (TarkinStream *s);
 
-uint32_t tarkin_write_set_bitrate (TarkinStream *s, uint32_t bitrate);
-uint32_t tarkin_write_frame (TarkinStream *s, uint8_t *buf);
-uint32_t tarkin_write_frame (TarkinStream *s, uint8_t *buf);
+extern int tarkin_stream_get_layer_desc (TarkinStream *s,
+                                         uint32_t layer_id,
+                                         TarkinVideoLayerDesc *desc);
+extern uint32_t tarkin_stream_read_header (TarkinStream *s);
+extern uint32_t tarkin_stream_read_frame (TarkinStream *s, uint8_t **buf);
+
+extern int tarkin_stream_write_layer_descs (TarkinStream *s,
+                                            uint32_t n_layers,
+                                            TarkinVideoLayerDesc desc []);
+extern uint32_t tarkin_stream_write_frame (TarkinStream *s, uint8_t **buf);
+extern void tarkin_stream_flush (TarkinStream *s);
 
 #endif
 

1.4       +5 -33     w3d/wavelet.c

Index: wavelet.c
===================================================================
RCS file: /usr/local/cvsroot/w3d/wavelet.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- wavelet.c	2001/06/25 07:56:07	1.3
+++ wavelet.c	2001/06/29 09:19:25	1.4
@@ -1,4 +1,5 @@
 #include <stdlib.h>
+#include <string.h>
 #include "wavelet.h"
 #include "rle.h"
 
@@ -184,7 +185,6 @@
 
 
 
-#if 1
 
 static inline
 void encode_quadrant (const Wavelet3DBuf* buf,
@@ -292,32 +292,8 @@
          decode_quadrant (buf,level,7,w1,h1,f1,s_stream,i_stream);
    }
 }
-#else
 
-static inline
-void encode_coefficients (const Wavelet3DBuf* buf,
-                          ENTROPY_CODER s_stream [],
-                          ENTROPY_CODER i_stream [])
-{
-   uint32_t i;
 
-   for (i=0; i<buf->width*buf->height*buf->frames; i++)
-      encode_coeff(s_stream, i_stream, buf->data[i]);
-}
-
-static inline
-void decode_coefficients (Wavelet3DBuf* buf,
-                          ENTROPY_CODER s_stream [],
-                          ENTROPY_CODER i_stream [])
-{
-   uint32_t i;
-
-   for (i=0; i<buf->width*buf->height*buf->frames; i++)
-      buf->data[i] = decode_coeff(s_stream, i_stream);
-}
-#endif
-
-
 static
 uint32_t setup_limittabs (ENTROPY_CODER significand_bitstream [],
                           ENTROPY_CODER insignificand_bitstream [],
@@ -342,6 +318,8 @@
       byte_count += bytes;
    }
 
+byte_count += 2 * 9 * sizeof(uint32_t);  /* 2 limittabs, coded binary */
+
    return byte_count;
 }
 
@@ -358,13 +336,11 @@
 
    for (i=0; i<9; i++) {
       *(uint32_t*) bitstream = significand_limittab[i];
-printf("significand_limittab[%i] == %u\n", i, significand_limittab[i]);
       bitstream += 4;
    }
 
    for (i=0; i<9; i++) {
       *(uint32_t*) bitstream = insignificand_limittab[i];
-printf("insignificand_limittab[%i] == %u\n", i, insignificand_limittab[i]);
       bitstream += 4;
    }
 
@@ -381,13 +357,11 @@
 
    for (i=0; i<9; i++) {
       significand_limittab[i] = *(uint32_t*) bitstream;
-//printf("> significand_limittab[%i] == %u\n", i, significand_limittab[i]);
       bitstream += 4;
    }
 
    for (i=0; i<9; i++) {
       insignificand_limittab[i] = *(uint32_t*) bitstream;
-//printf("> insignificand_limittab[%i] == %u\n", i, insignificand_limittab[i]);
       bitstream += 4;
    }
  
@@ -467,10 +441,8 @@
 
    encode_coefficients (buf, significand_bitstream, insignificand_bitstream);
 
-   byte_count = setup_limittabs (significand_bitstream,
-                                 insignificand_bitstream,
-                                 significand_limittab,
-                                 insignificand_limittab);
+   byte_count = setup_limittabs (significand_bitstream, insignificand_bitstream,
+                                 significand_limittab, insignificand_limittab);
 
    bitstream = write_limittabs (bitstream,
                                 significand_limittab, insignificand_limittab);

1.6       +143 -9    w3d/yuv.c

Index: yuv.c
===================================================================
RCS file: /usr/local/cvsroot/w3d/yuv.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- yuv.c	2001/06/25 07:56:07	1.5
+++ yuv.c	2001/06/29 09:19:25	1.6
@@ -1,18 +1,31 @@
 #include "yuv.h"
 
+static inline 
+uint8_t CLAMP(int16_t x)
+{
+   return  ((x > 255) ? 255 : (x < 0) ? 0 : x);
+}
 
-void rgb24_to_yuv (uint8_t *rgb, int16_t *y, int16_t *u, int16_t *v, uint32_t count, uint32_t rgbstride)
+
+
+
+
+void rgb24_to_yuv (uint8_t *rgb, Wavelet3DBuf *yuv [], uint32_t frame)
 {
+   int count = yuv[0]->width * yuv[0]->height;
+   int16_t *y = yuv[0]->data + frame * count;
+   int16_t *u = yuv[1]->data + frame * count;
+   int16_t *v = yuv[2]->data + frame * count;
    int i;
 
 #if defined(TARKIN_YUV_EXACT)
-   for (i=0; i<count; i++, rgb+=rgbstride) {
+   for (i=0; i<count; i++, rgb+=3) {
       y [i] = ((int16_t)  77 * rgb [0] + 150 * rgb [1] +  29 * rgb [2]) / 256;
       u [i] = ((int16_t) -44 * rgb [0] -  87 * rgb [1] + 131 * rgb [2]) / 256;
       v [i] = ((int16_t) 131 * rgb [0] - 110 * rgb [1] -  21 * rgb [2]) / 256;
    }
 #else
-   for (i=0; i<count; i++, rgb+=rgbstride) {
+   for (i=0; i<count; i++, rgb+=3) {
       v [i] = rgb [0] - rgb [1];
       u [i] = rgb [2] - rgb [1];
       y [i] = rgb [1] + (u [i] + v [i]) / 4;
@@ -21,29 +34,150 @@
 }
 
 
-static inline 
-uint8_t CLAMP(int16_t x)
+void yuv_to_rgb24 (Wavelet3DBuf *yuv [], uint8_t *rgb, uint32_t frame)
 {
-   return  ((x > 255) ? 255 : (x < 0) ? 0 : x);
+   int count = yuv[0]->width * yuv[0]->height;
+   int16_t *y = yuv[0]->data + frame * count;
+   int16_t *u = yuv[1]->data + frame * count;
+   int16_t *v = yuv[2]->data + frame * count;
+   int i;
+
+#if defined(TARKIN_YUV_EXACT)
+   for (i=0; i<count; i++, rgb+=3) {
+      rgb [0] = CLAMP(y [i] + 1.371 * v [i]);
+      rgb [1] = CLAMP(y [i] - 0.698 * v [i] - 0.336 * u [i]);
+      rgb [2] = CLAMP(y [i] + 1.732 * u [i]);
+   }
+#else
+   for (i=0; i<count; i++, rgb+=3) {
+      rgb [1] = CLAMP(y [i] - (u [i] + v [i]) / 4);
+      rgb [2] = CLAMP(u [i] + rgb [1]);
+      rgb [0] = CLAMP(v [i] + rgb [1]);
+   }
+#endif
+}
+
+
+void rgb32_to_yuv (uint8_t *rgb, Wavelet3DBuf *yuv [], uint32_t frame)
+{
+   int count = yuv[0]->width * yuv[0]->height;
+   int16_t *y = yuv[0]->data + frame * count;
+   int16_t *u = yuv[1]->data + frame * count;
+   int16_t *v = yuv[2]->data + frame * count;
+   int i;
+
+#if defined(TARKIN_YUV_EXACT)
+   for (i=0; i<count; i++, rgb+=4) {
+      y [i] = ((int16_t)  77 * rgb [0] + 150 * rgb [1] +  29 * rgb [2]) / 256;
+      u [i] = ((int16_t) -44 * rgb [0] -  87 * rgb [1] + 131 * rgb [2]) / 256;
+      v [i] = ((int16_t) 131 * rgb [0] - 110 * rgb [1] -  21 * rgb [2]) / 256;
+   }
+#else
+   for (i=0; i<count; i++, rgb+=4) {
+      v [i] = rgb [0] - rgb [1];
+      u [i] = rgb [2] - rgb [1];
+      y [i] = rgb [1] + (u [i] + v [i]) / 4;
+   }
+#endif
 }
 
 
-void yuv_to_rgb24 (int16_t *y, int16_t *u, int16_t *v, uint8_t *rgb, uint32_t count, uint32_t rgbstride)
+void yuv_to_rgb32 (Wavelet3DBuf *yuv [], uint8_t *rgb, uint32_t frame)
 {
+   int count = yuv[0]->width * yuv[0]->height;
+   int16_t *y = yuv[0]->data + frame * count;
+   int16_t *u = yuv[1]->data + frame * count;
+   int16_t *v = yuv[2]->data + frame * count;
    int i;
 
 #if defined(TARKIN_YUV_EXACT)
-   for (i=0; i<count; i++, rgb+=rgbstride) {
+   for (i=0; i<count; i++, rgb+=4) {
       rgb [0] = CLAMP(y [i] + 1.371 * v [i]);
       rgb [1] = CLAMP(y [i] - 0.698 * v [i] - 0.336 * u [i]);
       rgb [2] = CLAMP(y [i] + 1.732 * u [i]);
    }
 #else
-   for (i=0; i<count; i++, rgb+=rgbstride) {
+   for (i=0; i<count; i++, rgb+=4) {
       rgb [1] = CLAMP(y [i] - (u [i] + v [i]) / 4);
       rgb [2] = CLAMP(u [i] + rgb [1]);
       rgb [0] = CLAMP(v [i] + rgb [1]);
    }
 #endif
 }
+
+
+void rgba_to_yuv (uint8_t *rgba, Wavelet3DBuf *yuva [], uint32_t frame)
+{
+   int count = yuva[0]->width * yuva[0]->height;
+   int16_t *y = yuva[0]->data + frame * count;
+   int16_t *u = yuva[1]->data + frame * count;
+   int16_t *v = yuva[2]->data + frame * count;
+   int16_t *a = yuva[3]->data + frame * count;
+   int i;
+
+#if defined(TARKIN_YUV_EXACT)
+   for (i=0; i<count; i++, rgba+=4) {
+      y [i] = ((int16_t)  77 * rgba [0] + 150 * rgba [1] +  29 * rgba [2]) / 256;
+      u [i] = ((int16_t) -44 * rgba [0] -  87 * rgba [1] + 131 * rgba [2]) / 256;
+      v [i] = ((int16_t) 131 * rgba [0] - 110 * rgba [1] -  21 * rgba [2]) / 256;
+      a [i] = rgba [3];
+   }
+#else
+   for (i=0; i<count; i++, rgba+=4) {
+      v [i] = rgba [0] - rgba [1];
+      u [i] = rgba [2] - rgba [1];
+      y [i] = rgba [1] + (u [i] + v [i]) / 4;
+      a [i] = rgba [3];
+   }
+#endif
+}
+
+
+void yuv_to_rgba (Wavelet3DBuf *yuva [], uint8_t *rgba, uint32_t frame)
+{
+   int count = yuva[0]->width * yuva[0]->height;
+   int16_t *y = yuva[0]->data + frame * count;
+   int16_t *u = yuva[1]->data + frame * count;
+   int16_t *v = yuva[2]->data + frame * count;
+   int16_t *a = yuva[3]->data + frame * count;
+   int i;
+
+#if defined(TARKIN_YUV_EXACT)
+   for (i=0; i<count; i++, rgba+=4) {
+      rgba [0] = CLAMP(y [i] + 1.371 * v [i]);
+      rgba [1] = CLAMP(y [i] - 0.698 * v [i] - 0.336 * u [i]);
+      rgba [2] = CLAMP(y [i] + 1.732 * u [i]);
+      rgba [3] = a [i];
+   }
+#else
+   for (i=0; i<count; i++, rgba+=4) {
+      rgba [1] = CLAMP(y [i] - (u [i] + v [i]) / 4);
+      rgba [2] = CLAMP(u [i] + rgba [1]);
+      rgba [0] = CLAMP(v [i] + rgba [1]);
+      rgba [3] = a [i];
+   }
+#endif
+}
+
+void grayscale_to_y (uint8_t *rgba, Wavelet3DBuf *y [], uint32_t frame)
+{
+   int count = y[0]->width * y[0]->height;
+   int16_t *_y = y[0]->data + frame * count;
+   int i;
+
+   for (i=0; i<count; i++)
+      _y [i] = rgba [i];
+}
+
+
+void y_to_grayscale (Wavelet3DBuf *y [], uint8_t *rgba, uint32_t frame)
+{
+   int count = y[0]->width * y[0]->height;
+   int16_t *_y = y[0]->data + frame * count;
+   int i;
+
+   for (i=0; i<count; i++)
+      rgba [i] = CLAMP(_y[i]);
+}
+
 

1.4       +11 -2     w3d/yuv.h

Index: yuv.h
===================================================================
RCS file: /usr/local/cvsroot/w3d/yuv.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- yuv.h	2001/06/25 07:56:07	1.3
+++ yuv.h	2001/06/29 09:19:25	1.4
@@ -3,10 +3,19 @@
 #define __YUV_H
 
 #include <stdint.h>
+#include "wavelet.h"
 
-extern void rgb24_to_yuv (uint8_t *rgb, int16_t *y, int16_t *u, int16_t *v, uint32_t count, uint32_t rgbstride);
-extern void yuv_to_rgb24 (int16_t *y, int16_t *u, int16_t *v, uint8_t *rgb, uint32_t count, uint32_t rgbstride);
+extern void rgb24_to_yuv (uint8_t *rgb, Wavelet3DBuf *yuv [], uint32_t frame);
+extern void yuv_to_rgb24 (Wavelet3DBuf *yuv [], uint8_t *rgb, uint32_t frame);
 
+extern void rgb32_to_yuv (uint8_t *rgb, Wavelet3DBuf *yuv [], uint32_t frame);
+extern void yuv_to_rgb32 (Wavelet3DBuf *yuv [], uint8_t *rgb, uint32_t frame);
+
+extern void rgba_to_yuv (uint8_t *rgba, Wavelet3DBuf *yuva [], uint32_t frame);
+extern void yuv_to_rgba (Wavelet3DBuf *yuva [], uint8_t *rgba, uint32_t frame);
+
+extern void grayscale_to_y (uint8_t *rgba, Wavelet3DBuf *y [], uint32_t frame);
+extern void y_to_grayscale (Wavelet3DBuf *y [], uint8_t *rgba, uint32_t frame);
 
 #endif
 

1.1                  w3d/ppm.c

Index: ppm.c
===================================================================
/**
 *   This code has some serious problems with DOS-style CR/LF linebreaks.
 *   Simon already contributed better code, but there has been no attempt to
 *   use them for now.
 *   If you want do do this, please send me a patch.
 *
 *     - Holger
 */

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>

int read_ppm_info (char *fname, int *w, int *h)
{
   int i;
   FILE *file;

   file = fopen (fname, "r");

   if (!file) {
      fprintf(stderr, "Error opening '%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 *fname, uint8_t *buf, int w, int h)
{
   int i;
   long _w, _h;
   FILE *file;

   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 write_ppm (char *fname, uint8_t *rgb, int w, int h)
{
   FILE *outfile;

   outfile = fopen (fname, "w");

   if (!outfile) {
      printf ("error opening '%s' for writing !!!\n", fname);
      exit (-1);
   }

   fprintf (outfile, "P6\n%d %d\n%d\n", w, h, 255);
   fwrite (rgb, 3, w*h, outfile);
   fclose (outfile);
}

void write_ppm16 (char *fname, int16_t *rgb, int w, int h)
{
   int i;
   FILE *outfile;

   outfile = fopen (fname, "w");

   if (!outfile) {
      printf ("error opening '%s' for writing !!!\n", fname);
      exit (-1);
   }

   fprintf (outfile, "P6\n%d %d\n%d\n", w, h, 255);
   for (i=0; i<w*h; i++) {
      uint8_t c [3] = { rgb[i], rgb[i], rgb[i] };
      fwrite (c, 1, 3, outfile);
   }
   fclose (outfile);
}

1.1                  w3d/ppm.h

Index: ppm.h
===================================================================
#ifndef __PPM_H
#define __PPM_H

extern int read_ppm_info (char *fname, int *w, int *h);
extern int read_ppm (char *fname, uint8_t *buf, int w, int h);

extern void write_ppm (char *fname, uint8_t *buf, int w, int h);
extern void write_ppm16 (char *fname, int16_t *buf, int w, int h);

#endif

1.1                  w3d/tarkin-io.c

Index: tarkin-io.c
===================================================================
/**
 *   Not yet working.
 *
 *   Everything here should get oggetized. But for now I don't
 *   want to struggle with packets, so I simply write everything 
 *   binary.
 */

#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>

#include "tarkin-io.h"

#if __BYTE_ORDER == __LITTLE_ENDIAN

#define LE32_TO_CPU(x)
#define CPU_TO_LE32(x)

#elif __BYTE_ORDER == __BIG_ENDIAN

#define LE32_TO_CPU(x) x = (((x & 0x000000ff) << 24) | ((x & 0x0000ff00) << 8) \
                          | ((x & 0x00ff0000) >> 8)  | ((x & 0xff000000) << 24))
#define CPU_TO_LE32(x) x = (((x & 0x000000ff) << 24) | ((x & 0x0000ff00) << 8) \
                          | ((x & 0x00ff0000) >> 8)  | ((x & 0xff000000) << 24))

#else
#error  unknown endianess !!
#endif

int write_tarkin_header (int fd, TarkinStream *s)
{
   char signature [6] = "tarkin";
   uint32_t n_layers = s->n_layers;

   if (write (fd, signature, 6) < 6)
      return TARKIN_IO_ERROR;

   CPU_TO_LE32(n_layers);

   if (write (fd, &n_layers, 4) < 4)
      return TARKIN_IO_ERROR;

   return TARKIN_OK;
}

int write_layer_descs (int fd, TarkinStream *s)
{
   int i;
   TarkinVideoLayer layer;

   for (i=0; i<s->n_layers; i++) {
      memcpy(&layer, &s->layer[i], sizeof(TarkinVideoLayer));

      CPU_TO_LE32(layer.width);
      CPU_TO_LE32(layer.height);
      CPU_TO_LE32(layer.frames_per_buf);
      CPU_TO_LE32(layer.bitrate);
      CPU_TO_LE32(layer.format);

      if (write (fd, &layer, sizeof(TarkinVideoLayer)) < sizeof(TarkinVideoLayer)) {
         return TARKIN_IO_ERROR;
      }
   }

   return TARKIN_OK;
}

int write_tarkin_bitstream (int fd, uint8_t *bitstream, uint32_t len)
{
   uint32_t bytes = len;

   CPU_TO_LE32(bytes);

   return (write (fd, &bytes, 4) + write (fd, bitstream, bytes));
}

int read_tarkin_header (int fd, TarkinStream *s)
{
   char signature [6];

   if (read (fd, signature, 6) < 6)
      return TARKIN_IO_ERROR;

   if (!strncmp(signature, "tarkin", 6) == 0)
      return TARKIN_SIGNATURE_NOT_FOUND;

   if (read (fd, &s->n_layers, 4) < 4)
      return TARKIN_IO_ERROR;

   LE32_TO_CPU(s->n_layers);

   return TARKIN_OK;
}

int read_layer_descs (int fd, TarkinStream *s)
{
   int i;

   s->layer = (TarkinVideoLayer*) calloc (1, s->n_layers * sizeof(TarkinVideoLayer));

   for (i=0; i<s->n_layers; i++) {
      if (read (fd, &s->layer[i], sizeof(TarkinVideoLayer)) < sizeof(TarkinVideoLayer)) {
         tarkin_stream_destroy (s);
         return TARKIN_IO_ERROR;
      }
      LE32_TO_CPU(s->layer[i].width);
      LE32_TO_CPU(s->layer[i].height);
      LE32_TO_CPU(s->layer[i].frames_per_buf);
      LE32_TO_CPU(s->layer[i].bitrate);
      LE32_TO_CPU(s->layer[i].format);
   }

   return TARKIN_OK;
}

int read_tarkin_bitstream (int fd, uint8_t *bitstream)
{
   uint32_t len;

   if (read (fd, &len, 4) < 4 || len == 0)
      return 0;

   LE32_TO_CPU(len);

   return read (fd, bitstream, len);
}

1.1                  w3d/tarkin-io.h

Index: tarkin-io.h
===================================================================
#ifndef __TARKIN_IO_H
#define __TARKIN_IO_H

#include "tarkin.h"

extern int write_tarkin_header (int fd, TarkinStream *s);
extern int write_layer_descs (int fd, TarkinStream *s);
extern int write_tarkin_bitstream (int fd, uint8_t *bitstream, uint32_t len);

extern int read_tarkin_header (int fd, TarkinStream *s);
extern int read_layer_descs (int fd, TarkinStream *s);
extern int read_tarkin_bitstream (int fd, uint8_t *bitstream);

#endif

1.1                  w3d/tarkin_dec.c

Index: tarkin_dec.c
===================================================================
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "tarkin.h"
#include "ppm.h"

int main (int argc, char **argv)
{
   char *fname = "stream.tarkin";
   char ofname [11];
   uint32_t frame = 0;
   uint8_t *rgb;
   int fd;
   TarkinStream *tarkin_stream;
   uint32_t n_layers;
   TarkinVideoLayerDesc layer;

   if (argc == 2) {
      fname = argv[1];
   } else if (argc != 1) {
      printf ("\n usage: %s <tarkin_stream>\n\n", argv[0]);
      exit (-1);
   }

   if ((fd = open (fname, O_RDONLY)) < 0) {
      printf ("error opening '%s'\n", fname);
      exit (-1);
   }

   tarkin_stream = tarkin_stream_new (fd);
   n_layers = tarkin_stream_read_header (tarkin_stream);

   if (n_layers == 0) {
      printf ("empty tarkin stream !!!\n");
      exit (-1);
   }

   tarkin_stream_get_layer_desc (tarkin_stream, 0, &layer);

   rgb  = malloc (layer.width * layer.height * 3);

   while (tarkin_stream_read_frame (tarkin_stream, &rgb) != 0xffffffff) {
      snprintf(ofname, 11, "out%03d.ppm", frame);
      printf ("write '%s'\n", ofname);
      write_ppm (ofname, rgb, layer.width, layer.height);

      frame ++;
   };

   free (rgb);
   tarkin_stream_destroy (tarkin_stream);
   close (fd);

   return 0;
}

1.1                  w3d/tarkin_enc.c

Index: tarkin_enc.c
===================================================================
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "tarkin.h"
#include "ppm.h"

int main (int argc, char **argv)
{
   char *fmt = "%i.ppm";
   char fname[256];
   uint32_t frame = 0;
   uint8_t *rgb;
   int ylimit, ulimit, vlimit;
   int a_moments, s_moments;
   int fd;
   TarkinStream *tarkin_stream;
   TarkinVideoLayerDesc layer [] = { { 0, 0, 1, 5000, TARKIN_RGB24 } };

   if (argc == 1) {
      ylimit = 1000;
      ulimit = 150;
      vlimit = 150;
      a_moments = 2;
      s_moments = 2;
   } else if (argc == 7) {
      fmt = argv[1];
      ylimit = strtol (argv[2], 0, 0);
      ulimit = strtol (argv[3], 0, 0);
      vlimit = strtol (argv[4], 0, 0);
      a_moments = strtol (argv[5], 0, 0);
      s_moments = strtol (argv[6], 0, 0);
   } else {
      printf ("\n"
        " usage: %s <input filename format string> <ylimit> <ulimit> <vlimit> <a_m> <s_m>\n"
        "\n"
        "   input ppm filename format:  optional, \"%%i.ppm\" by default\n"
        "   ylimit, ulimit, vlimit:     cut Y/U/V bitstream after limit bytes/frame\n"
        "   a_m, s_m:                   number of vanishing moments of the\n"
        "                               analysis/synthesis filter, (2,2) by default\n"
        "\n", argv[0]);
      exit (-1);
   }

   snprintf (fname, 256, fmt, 0);
   if (read_ppm_info (fname, &layer[0].width, &layer[0].height) < 0)
      exit (-1);

   rgb  = malloc (layer[0].width * layer[0].height * 3);

   if ((fd = open ("stream.tarkin", O_CREAT | O_RDWR | O_TRUNC, 0644)) < 0) {
      printf ("error opening '%s' for writing !\n", "stream.tarkin");
      exit (-1);
   }

   tarkin_stream = tarkin_stream_new (fd);
   tarkin_stream_write_layer_descs (tarkin_stream, 1, layer);

   do {
      snprintf (fname, 256, fmt, frame);
      printf ("read '");
      printf (fname, frame);
      printf ("'");

      if (read_ppm (fname, rgb, layer[0].width, layer[0].height) < 0)
      {
         printf (" failed.\n");
         break;
      }
      printf ("\n");

      tarkin_stream_write_frame (tarkin_stream, &rgb);
      frame++;
   } while (0);

   free (rgb);
   tarkin_stream_destroy (tarkin_stream);
   close (fd);

   return 0;
}

--- >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