summaryrefslogtreecommitdiffstats
path: root/ext/jpeg/smokecodec.c
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2004-10-04 16:53:48 +0000
committerWim Taymans <wim.taymans@gmail.com>2004-10-04 16:53:48 +0000
commitb90716dd184e3a270fc31ab39307548fe16337cc (patch)
treee204108290be35fe11b3ecde34ebbc60396cdb5a /ext/jpeg/smokecodec.c
parentd2ba80e45ee0a5b90aa2be7571efb92a560bd1c0 (diff)
ext/jpeg/: Updated smoke, new bitstream, allows embedding in ogg.
Original commit message from CVS: * ext/jpeg/gstjpeg.c: (smoke_type_find), (plugin_init): * ext/jpeg/gstsmokedec.c: (gst_smokedec_init), (gst_smokedec_chain): * ext/jpeg/gstsmokedec.h: * ext/jpeg/gstsmokeenc.c: (gst_smokeenc_class_init), (gst_smokeenc_init), (gst_smokeenc_resync), (gst_smokeenc_chain): * ext/jpeg/gstsmokeenc.h: * ext/jpeg/smokecodec.c: (smokecodec_encode_new), (smokecodec_decode_new), (smokecodec_info_free), (smokecodec_set_quality), (smokecodec_get_quality), (smokecodec_set_threshold), (smokecodec_get_threshold), (smokecodec_set_bitrate), (smokecodec_get_bitrate), (find_best_size), (abs_diff), (put), (smokecodec_encode_id), (smokecodec_encode), (smokecodec_parse_id), (smokecodec_parse_header), (smokecodec_decode): * ext/jpeg/smokecodec.h: * ext/jpeg/smokeformat.h: Updated smoke, new bitstream, allows embedding in ogg.
Diffstat (limited to 'ext/jpeg/smokecodec.c')
-rw-r--r--ext/jpeg/smokecodec.c130
1 files changed, 102 insertions, 28 deletions
diff --git a/ext/jpeg/smokecodec.c b/ext/jpeg/smokecodec.c
index cb16827f..fb2dbe6e 100644
--- a/ext/jpeg/smokecodec.c
+++ b/ext/jpeg/smokecodec.c
@@ -34,15 +34,17 @@
#include <jpeglib.h>
#include "smokecodec.h"
+#include "smokeformat.h"
//#define DEBUG(a...) printf( a );
#define DEBUG(a,...)
-
struct _SmokeCodecInfo
{
unsigned int width;
unsigned int height;
+ unsigned int fps_num;
+ unsigned int fps_denom;
unsigned int minquality;
unsigned int maxquality;
@@ -112,7 +114,9 @@ smokecodec_term_source (j_decompress_ptr cinfo)
int
smokecodec_encode_new (SmokeCodecInfo ** info,
- const unsigned int width, const unsigned int height)
+ const unsigned int width,
+ const unsigned int height,
+ const unsigned int fps_num, const unsigned int fps_denom)
{
SmokeCodecInfo *newinfo;
int i, j;
@@ -129,6 +133,8 @@ smokecodec_encode_new (SmokeCodecInfo ** info,
}
newinfo->width = width;
newinfo->height = height;
+ newinfo->fps_num = fps_num;
+ newinfo->fps_denom = fps_denom;
/* setup jpeglib */
memset (&newinfo->cinfo, 0, sizeof (newinfo->cinfo));
@@ -200,7 +206,7 @@ smokecodec_encode_new (SmokeCodecInfo ** info,
int
smokecodec_decode_new (SmokeCodecInfo ** info)
{
- return smokecodec_encode_new (info, 16, 16);
+ return smokecodec_encode_new (info, 16, 16, 1, 1);
}
int
@@ -349,6 +355,25 @@ put (const unsigned char *src, unsigned char *dest,
/* encoding */
SmokeCodecResult
+smokecodec_encode_id (SmokeCodecInfo * info,
+ unsigned char *out, unsigned int *outsize)
+{
+ int i;
+
+ *out++ = SMOKECODEC_TYPE_ID;
+ for (i = 0; i < strlen (SMOKECODEC_ID_STRING); i++) {
+ *out++ = SMOKECODEC_ID_STRING[i];
+ }
+ *out++ = 0;
+ *out++ = 1;
+ *out++ = 0;
+
+ *outsize = 9;
+
+ return SMOKECODEC_OK;
+}
+
+SmokeCodecResult
smokecodec_encode (SmokeCodecInfo * info,
const unsigned char *in,
SmokeCodecFlags flags, unsigned char *out, unsigned int *outsize)
@@ -384,13 +409,24 @@ smokecodec_encode (SmokeCodecInfo * info,
max = blocks_w * blocks_h;
+ out[IDX_TYPE] = SMOKECODEC_TYPE_DATA;
+
#define STORE16(var, pos, x) \
- var[pos] = (x >> 8); \
+ var[pos] = (x >> 8); \
var[pos+1] = (x & 0xff);
+#define STORE32(var, pos, x) \
+ var[pos] = ((x >> 24) & 0xff); \
+ var[pos+1] = ((x >> 16) & 0xff); \
+ var[pos+2] = ((x >> 8) & 0xff); \
+ var[pos+3] = (x & 0xff);
/* write dimension */
- STORE16 (out, 0, width);
- STORE16 (out, 2, height);
+ STORE16 (out, IDX_WIDTH, width);
+ STORE16 (out, IDX_HEIGHT, height);
+
+ /* write framerate */
+ STORE32 (out, IDX_FPS_NUM, info->fps_num);
+ STORE32 (out, IDX_FPS_DENOM, info->fps_denom);
if (!(flags & SMOKECODEC_KEYFRAME)) {
int block = 0;
@@ -400,7 +436,7 @@ smokecodec_encode (SmokeCodecInfo * info,
for (j = 0; j < width; j += 2 * DCTSIZE) {
s = abs_diff (ip, op, width);
if (s >= threshold) {
- STORE16 (out, blocks * 2 + 10, block);
+ STORE16 (out, blocks * 2 + IDX_BLOCKS, block);
blocks++;
}
@@ -422,13 +458,13 @@ smokecodec_encode (SmokeCodecInfo * info,
blocks = 0;
encoding = max;
}
- STORE16 (out, 6, blocks);
- out[4] = (flags & 0xff);
+ STORE16 (out, IDX_NUM_BLOCKS, blocks);
+ out[IDX_FLAGS] = (flags & 0xff);
DEBUG ("blocks %d, encoding %d\n", blocks, encoding);
- info->jdest.next_output_byte = &out[blocks * 2 + 12];
- info->jdest.free_in_buffer = (*outsize) - 12;
+ info->jdest.next_output_byte = &out[blocks * 2 + OFFS_PICT];
+ info->jdest.free_in_buffer = (*outsize) - OFFS_PICT;
if (encoding > 0) {
int quality;
@@ -461,7 +497,7 @@ smokecodec_encode (SmokeCodecInfo * info,
if (flags & SMOKECODEC_KEYFRAME)
pos = i;
else
- pos = (out[i * 2 + 10] << 8) | (out[i * 2 + 11]);
+ pos = (out[i * 2 + IDX_BLOCKS] << 8) | (out[i * 2 + IDX_BLOCKS + 1]);
x = pos % (width / (DCTSIZE * 2));
y = pos / (width / (DCTSIZE * 2));
@@ -488,11 +524,10 @@ smokecodec_encode (SmokeCodecInfo * info,
jpeg_finish_compress (&info->cinfo);
}
- size = ((((*outsize) - 12 - info->jdest.free_in_buffer) + 3) & ~3);
- out[8] = size >> 8;
- out[9] = size & 0xff;
+ size = ((((*outsize) - OFFS_PICT - info->jdest.free_in_buffer) + 3) & ~3);
+ STORE16 (out, IDX_SIZE, size);
- *outsize = size + blocks * 2 + 12;
+ *outsize = size + blocks * 2 + OFFS_PICT;
DEBUG ("outsize %d\n", *outsize);
// and decode in reference frame again
@@ -505,24 +540,62 @@ smokecodec_encode (SmokeCodecInfo * info,
return SMOKECODEC_OK;
}
+SmokeCodecResult
+smokecodec_parse_id (SmokeCodecInfo * info,
+ const unsigned char *in, const unsigned int insize)
+{
+ int i;
+
+ if (insize < 4 + strlen (SMOKECODEC_ID_STRING)) {
+ return SMOKECODEC_WRONGVERSION;
+ }
+
+ if (*in++ != SMOKECODEC_TYPE_ID)
+ return SMOKECODEC_ERROR;
+
+ for (i = 0; i < strlen (SMOKECODEC_ID_STRING); i++) {
+ if (*in++ != SMOKECODEC_ID_STRING[i])
+ return SMOKECODEC_ERROR;
+ }
+ if (*in++ != 0 || *in++ != 1 || *in++ != 0)
+ return SMOKECODEC_ERROR;
+
+ return SMOKECODEC_OK;
+}
+
+#define READ16(var, pos, x) \
+ x = var[pos]<<8 | var[pos+1];
+
+#define READ32(var, pos, x) \
+ x = var[pos]<<24 | var[pos+1]<<16 | \
+ var[pos+2]<<8 | var[pos+3];
+
/* decoding */
SmokeCodecResult
smokecodec_parse_header (SmokeCodecInfo * info,
const unsigned char *in,
const unsigned int insize,
- SmokeCodecFlags * flags, unsigned int *width, unsigned int *height)
+ SmokeCodecFlags * flags,
+ unsigned int *width,
+ unsigned int *height, unsigned int *fps_num, unsigned int *fps_denom)
{
- *width = in[0] << 8 | in[1];
- *height = in[2] << 8 | in[3];
- *flags = in[4];
+ READ16 (in, IDX_WIDTH, *width);
+ READ16 (in, IDX_HEIGHT, *height);
+ *flags = in[IDX_FLAGS];
+ READ32 (in, IDX_FPS_NUM, *fps_num);
+ READ32 (in, IDX_FPS_DENOM, *fps_denom);
- if (info->width != *width || info->height != *height) {
+ if (info->width != *width ||
+ info->height != *height ||
+ info->fps_num != *fps_num || info->fps_denom != *fps_denom) {
DEBUG ("new width: %d %d\n", *width, *height);
info->reference = realloc (info->reference, 3 * ((*width) * (*height)) / 2);
info->width = *width;
info->height = *height;
+ info->fps_num = *fps_num;
+ info->fps_denom = *fps_denom;
}
return SMOKECODEC_OK;
@@ -533,6 +606,7 @@ smokecodec_decode (SmokeCodecInfo * info,
const unsigned char *in, const unsigned int insize, unsigned char *out)
{
unsigned int width, height;
+ unsigned int fps_num, fps_denom;
SmokeCodecFlags flags;
int i, j;
int blocks_w, blocks_h;
@@ -542,9 +616,10 @@ smokecodec_decode (SmokeCodecInfo * info,
unsigned char *op;
int res;
- smokecodec_parse_header (info, in, insize, &flags, &width, &height);
+ smokecodec_parse_header (info, in, insize, &flags, &width, &height,
+ &fps_num, &fps_denom);
- blocks = in[6] << 8 | in[7];
+ READ16 (in, IDX_NUM_BLOCKS, blocks);
DEBUG ("blocks %d\n", blocks);
if (flags & SMOKECODEC_KEYFRAME)
@@ -552,12 +627,11 @@ smokecodec_decode (SmokeCodecInfo * info,
else
decoding = blocks;
-
if (decoding > 0) {
- info->jsrc.next_input_byte = &in[blocks * 2 + 12];
- info->jsrc.bytes_in_buffer = insize - (blocks * 2 + 12);
+ info->jsrc.next_input_byte = &in[blocks * 2 + OFFS_PICT];
+ info->jsrc.bytes_in_buffer = insize - (blocks * 2 + OFFS_PICT);
- DEBUG ("header %02x %d\n", in[blocks * 2 + 12], insize);
+ DEBUG ("header %02x %d\n", in[blocks * 2 + OFFS_PICT], insize);
res = jpeg_read_header (&info->dinfo, TRUE);
DEBUG ("header %d %d %d\n", res, info->dinfo.image_width,
info->dinfo.image_height);
@@ -590,7 +664,7 @@ smokecodec_decode (SmokeCodecInfo * info,
if (flags & SMOKECODEC_KEYFRAME)
pos = blockptr;
else
- pos = (in[blockptr * 2 + 10] << 8) | (in[blockptr * 2 + 11]);
+ READ16 (in, blockptr * 2 + IDX_BLOCKS, pos);
x = pos % (width / (DCTSIZE * 2));
y = pos / (width / (DCTSIZE * 2));