From c57821405a657216e41e9c9e8ddaed9996af2350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Sat, 22 Dec 2007 23:08:08 +0100 Subject: Rename libxinvadec directory in video_dec. --HG-- rename : src/libxinevdec/Makefile.am => src/video_dec/Makefile.am rename : src/libxinevdec/bitplane.c => src/video_dec/bitplane.c rename : src/libxinevdec/foovideo.c => src/video_dec/foovideo.c rename : src/libxinevdec/gdkpixbuf.c => src/video_dec/gdkpixbuf.c rename : src/libxinevdec/image.c => src/video_dec/image.c rename : src/libxinevdec/rgb.c => src/video_dec/rgb.c rename : src/libxinevdec/yuv.c => src/video_dec/yuv.c --- src/Makefile.am | 2 +- src/libxinevdec/Makefile.am | 38 -- src/libxinevdec/bitplane.c | 1554 ------------------------------------------- src/libxinevdec/foovideo.c | 281 -------- src/libxinevdec/gdkpixbuf.c | 294 -------- src/libxinevdec/image.c | 273 -------- src/libxinevdec/rgb.c | 447 ------------- src/libxinevdec/yuv.c | 373 ----------- src/video_dec/Makefile.am | 38 ++ src/video_dec/bitplane.c | 1554 +++++++++++++++++++++++++++++++++++++++++++ src/video_dec/foovideo.c | 281 ++++++++ src/video_dec/gdkpixbuf.c | 294 ++++++++ src/video_dec/image.c | 273 ++++++++ src/video_dec/rgb.c | 447 +++++++++++++ src/video_dec/yuv.c | 373 +++++++++++ 15 files changed, 3261 insertions(+), 3261 deletions(-) delete mode 100644 src/libxinevdec/Makefile.am delete mode 100644 src/libxinevdec/bitplane.c delete mode 100644 src/libxinevdec/foovideo.c delete mode 100644 src/libxinevdec/gdkpixbuf.c delete mode 100644 src/libxinevdec/image.c delete mode 100644 src/libxinevdec/rgb.c delete mode 100644 src/libxinevdec/yuv.c create mode 100644 src/video_dec/Makefile.am create mode 100644 src/video_dec/bitplane.c create mode 100644 src/video_dec/foovideo.c create mode 100644 src/video_dec/gdkpixbuf.c create mode 100644 src/video_dec/image.c create mode 100644 src/video_dec/rgb.c create mode 100644 src/video_dec/yuv.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 816cfa07c..330b099a0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,6 +7,7 @@ SUBDIRS = \ audio_out \ audio_dec \ video_out \ + video_dec \ dxr3 \ input \ demuxers \ @@ -18,7 +19,6 @@ SUBDIRS = \ libspudvb \ libsputext \ libw32dll \ - libxinevdec \ libreal \ post \ combined \ diff --git a/src/libxinevdec/Makefile.am b/src/libxinevdec/Makefile.am deleted file mode 100644 index 321d70c1f..000000000 --- a/src/libxinevdec/Makefile.am +++ /dev/null @@ -1,38 +0,0 @@ -include $(top_srcdir)/misc/Makefile.common - -AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) -AM_LDFLAGS = $(xineplug_ldflags) - -EXTRA_DIST = foovideo.c - -if ENABLE_IMAGEMAGICK -image_module = xineplug_decode_image.la -endif - -if ENABLE_GDK_PIXBUF -gdkpixbuf_module = xineplug_decode_gdk_pixbuf.la -endif - -xineplug_LTLIBRARIES = $(image_module) \ - $(gdkpixbuf_module) \ - $(theora_module) \ - xineplug_decode_bitplane.la \ - xineplug_decode_rgb.la \ - xineplug_decode_yuv.la - -xineplug_decode_bitplane_la_SOURCES = bitplane.c -xineplug_decode_bitplane_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) - -xineplug_decode_rgb_la_SOURCES = rgb.c -xineplug_decode_rgb_la_LIBADD = $(XINE_LIB) - -xineplug_decode_yuv_la_SOURCES = yuv.c -xineplug_decode_yuv_la_LIBADD = $(XINE_LIB) - -xineplug_decode_image_la_SOURCES = image.c -xineplug_decode_image_la_LIBADD = $(XINE_LIB) $(DYNAMIC_LD_LIBS) $(WAND_LIBS) -xineplug_decode_image_la_CFLAGS = $(AM_CFLAGS) $(WAND_CFLAGS) - -xineplug_decode_gdk_pixbuf_la_SOURCES = gdkpixbuf.c -xineplug_decode_gdk_pixbuf_la_LIBADD = $(XINE_LIB) $(DYNAMIC_LD_LIBS) $(GDK_PIXBUF_LIBS) -xineplug_decode_gdk_pixbuf_la_CFLAGS = $(AM_CFLAGS) $(GDK_PIXBUF_CFLAGS) diff --git a/src/libxinevdec/bitplane.c b/src/libxinevdec/bitplane.c deleted file mode 100644 index 327e14aee..000000000 --- a/src/libxinevdec/bitplane.c +++ /dev/null @@ -1,1554 +0,0 @@ -/* - * Copyright (C) 2004 the xine project - * - * This file is part of xine, a free video player. - * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * Bitplane "Decoder" by Manfred Tremmel (Manfred.Tremmel@iiv.de) - * Converts Amiga typical bitplane pictures to a YUV2 map - * suitable for display under xine. It's based on the rgb-decoder - * and the development documentation from the Amiga Developer CD - * - * Supported formats: - * - uncompressed and byterun1 compressed ILBM data - * - IFF ANIM compression methods OPT 5, 7 (long and short) and - * 8 (long and short) - * - untested (found no testfiles) IFF-ANIM OPT 3, 4 and 6 - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "bswap.h" - -#include "demuxers/iff.h" - -#define IFF_REPLACE_BYTE_SIMPLE(ptr, old_data, new_data, colorindexx ) { \ - register uint8_t *index_ptr = ptr; \ - register uint8_t colorindex = colorindexx; \ - *index_ptr -= ((old_data & 0x80) ? colorindex : 0); \ - *index_ptr++ += ((new_data & 0x80) ? colorindex : 0); \ - *index_ptr -= ((old_data & 0x40) ? colorindex : 0); \ - *index_ptr++ += ((new_data & 0x40) ? colorindex : 0); \ - *index_ptr -= ((old_data & 0x20) ? colorindex : 0); \ - *index_ptr++ += ((new_data & 0x20) ? colorindex : 0); \ - *index_ptr -= ((old_data & 0x10) ? colorindex : 0); \ - *index_ptr++ += ((new_data & 0x10) ? colorindex : 0); \ - *index_ptr -= ((old_data & 0x08) ? colorindex : 0); \ - *index_ptr++ += ((new_data & 0x08) ? colorindex : 0); \ - *index_ptr -= ((old_data & 0x04) ? colorindex : 0); \ - *index_ptr++ += ((new_data & 0x04) ? colorindex : 0); \ - *index_ptr -= ((old_data & 0x02) ? colorindex : 0); \ - *index_ptr++ += ((new_data & 0x02) ? colorindex : 0); \ - *index_ptr -= ((old_data & 0x01) ? colorindex : 0); \ - *index_ptr += ((new_data & 0x01) ? colorindex : 0); \ - old_data = new_data; \ -} - -#define IFF_REPLACE_BYTE(ptr, yuvy, yuvu, yuvv, yuv_palette, old_data, new_data, colorindexx ) { \ - register uint8_t *index_ptr = ptr; \ - register uint8_t colorindex = colorindexx; \ - register uint8_t *yuv_y = yuvy; \ - register uint8_t *yuv_u = yuvu; \ - register uint8_t *yuv_v = yuvv; \ - *index_ptr -= ((old_data & 0x80) ? colorindex : 0); \ - *index_ptr += ((new_data & 0x80) ? colorindex : 0); \ - yuv_index = *index_ptr++ * 4; \ - *yuv_y++ = yuv_palette[yuv_index++]; \ - *yuv_u++ = yuv_palette[yuv_index++]; \ - *yuv_v++ = yuv_palette[yuv_index]; \ - *index_ptr -= ((old_data & 0x40) ? colorindex : 0); \ - *index_ptr += ((new_data & 0x40) ? colorindex : 0); \ - yuv_index = *index_ptr++ * 4; \ - *yuv_y++ = yuv_palette[yuv_index++]; \ - *yuv_u++ = yuv_palette[yuv_index++]; \ - *yuv_v++ = yuv_palette[yuv_index]; \ - *index_ptr -= ((old_data & 0x20) ? colorindex : 0); \ - *index_ptr += ((new_data & 0x20) ? colorindex : 0); \ - yuv_index = *index_ptr++ * 4; \ - *yuv_y++ = yuv_palette[yuv_index++]; \ - *yuv_u++ = yuv_palette[yuv_index++]; \ - *yuv_v++ = yuv_palette[yuv_index]; \ - *index_ptr -= ((old_data & 0x10) ? colorindex : 0); \ - *index_ptr += ((new_data & 0x10) ? colorindex : 0); \ - yuv_index = *index_ptr++ * 4; \ - *yuv_y++ = yuv_palette[yuv_index++]; \ - *yuv_u++ = yuv_palette[yuv_index++]; \ - *yuv_v++ = yuv_palette[yuv_index]; \ - *index_ptr -= ((old_data & 0x08) ? colorindex : 0); \ - *index_ptr += ((new_data & 0x08) ? colorindex : 0); \ - yuv_index = *index_ptr++ * 4; \ - *yuv_y++ = yuv_palette[yuv_index++]; \ - *yuv_u++ = yuv_palette[yuv_index++]; \ - *yuv_v++ = yuv_palette[yuv_index]; \ - *index_ptr -= ((old_data & 0x04) ? colorindex : 0); \ - *index_ptr += ((new_data & 0x04) ? colorindex : 0); \ - yuv_index = *index_ptr++ * 4; \ - *yuv_y++ = yuv_palette[yuv_index++]; \ - *yuv_u++ = yuv_palette[yuv_index++]; \ - *yuv_v++ = yuv_palette[yuv_index]; \ - *index_ptr -= ((old_data & 0x02) ? colorindex : 0); \ - *index_ptr += ((new_data & 0x02) ? colorindex : 0); \ - yuv_index = *index_ptr++ * 4; \ - *yuv_y++ = yuv_palette[yuv_index++]; \ - *yuv_u++ = yuv_palette[yuv_index++]; \ - *yuv_v++ = yuv_palette[yuv_index]; \ - *index_ptr -= ((old_data & 0x01) ? colorindex : 0); \ - *index_ptr += ((new_data & 0x01) ? colorindex : 0); \ - yuv_index = *index_ptr * 4; \ - *yuv_y = yuv_palette[yuv_index++]; \ - *yuv_u = yuv_palette[yuv_index++]; \ - *yuv_v = yuv_palette[yuv_index]; \ - old_data = new_data; \ -} - -#define IFF_REPLACE_SHORT_SIMPLE(ptr_s, old_data_s, new_data_s, colorindexx_s ) { \ - uint8_t *xindex_ptr = (uint8_t *)ptr_s; \ - uint8_t *xold_data = (uint8_t *)old_data_s; \ - uint8_t *xnew_data = (uint8_t *)new_data_s; \ - IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_s ); \ - xindex_ptr += 8; \ - xold_data++; \ - xnew_data++; \ - IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_s ); \ -} - -#define IFF_REPLACE_SHORT(ptr_s, yuvy_s, yuvu_s, yuvv_s, yuv_palette_s, old_data_s, new_data_s, colorindexx_s ) { \ - uint8_t *xindex_ptr = (uint8_t *)ptr_s; \ - uint8_t *xold_data = (uint8_t *)old_data_s; \ - uint8_t *xnew_data = (uint8_t *)new_data_s; \ - uint8_t *xyuv_y = yuvy_s; \ - uint8_t *xyuv_u = yuvu_s; \ - uint8_t *xyuv_v = yuvv_s; \ - IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_s, *xold_data, *xnew_data, colorindexx_s ); \ - xindex_ptr += 8; \ - xold_data++; \ - xnew_data++; \ - xyuv_y += 8; \ - xyuv_u += 8; \ - xyuv_v += 8; \ - IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_s, *xold_data, *xnew_data, colorindexx_s ); \ -} - -#define IFF_REPLACE_LONG_SIMPLE(ptr_l, old_data_l, new_data_l, colorindexx_l ) { \ - uint8_t *xindex_ptr = (uint8_t *)ptr_l; \ - uint8_t *xold_data = (uint8_t *)old_data_l; \ - uint8_t *xnew_data = (uint8_t *)new_data_l; \ - IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_l ); \ - xindex_ptr += 8; \ - xold_data++; \ - xnew_data++; \ - IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_l ); \ - xindex_ptr += 8; \ - xold_data++; \ - xnew_data++; \ - IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_l ); \ - xindex_ptr += 8; \ - xold_data++; \ - xnew_data++; \ - IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_l ); \ -} - -#define IFF_REPLACE_LONG(ptr_l, yuvy_l, yuvu_l, yuvv_l, yuv_palette_l, old_data_l, new_data_l, colorindexx_l ) { \ - uint8_t *xindex_ptr = (uint8_t *)ptr_l; \ - uint8_t *xold_data = (uint8_t *)old_data_l; \ - uint8_t *xnew_data = (uint8_t *)new_data_l; \ - uint8_t *xyuv_y = yuvy_l; \ - uint8_t *xyuv_u = yuvu_l; \ - uint8_t *xyuv_v = yuvv_l; \ - IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_l, *xold_data, *xnew_data, colorindexx_l ); \ - xindex_ptr += 8; \ - xold_data++; \ - xnew_data++; \ - xyuv_y += 8; \ - xyuv_u += 8; \ - xyuv_v += 8; \ - IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_l, *xold_data, *xnew_data, colorindexx_l ); \ - xindex_ptr += 8; \ - xold_data++; \ - xnew_data++; \ - xyuv_y += 8; \ - xyuv_u += 8; \ - xyuv_v += 8; \ - IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_l, *xold_data, *xnew_data, colorindexx_l ); \ - xindex_ptr += 8; \ - xold_data++; \ - xnew_data++; \ - xyuv_y += 8; \ - xyuv_u += 8; \ - xyuv_v += 8; \ - IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_l, *xold_data, *xnew_data, colorindexx_l ); \ -} - -typedef struct { - video_decoder_class_t decoder_class; -} bitplane_class_t; - -typedef struct bitplane_decoder_s { - video_decoder_t video_decoder; /* parent video decoder structure */ - - bitplane_class_t *class; - xine_stream_t *stream; - - /* these are traditional variables in a video decoder object */ - uint64_t video_step; /* frame duration in pts units */ - int decoder_ok; /* current decoder status */ - int skipframes; /* 0 = draw picture, 1 = skip it */ - int framenumber; - - unsigned char *buf; /* the accumulated buffer data */ - int bufsize; /* the maximum size of buf */ - int size; /* the current size of buf */ - int size_uk; /* size of unkompressed bitplane */ - - int width; /* the width of a video frame */ - int height; /* the height of a video frame */ - int num_pixel; /* number pixel */ - double ratio; /* the width to height ratio */ - int bytes_per_pixel; - int num_bitplanes; - int camg_mode; - int is_ham; - - unsigned char yuv_palette[256 * 4]; - unsigned char rgb_palette[256 * 4]; - yuv_planes_t yuv_planes; - yuv_planes_t yuv_planes_hist; - - uint8_t *buf_uk; /* uncompressed buffer */ - uint8_t *buf_uk_hist; /* uncompressed buffer historic */ - uint8_t *index_buf; /* index buffer (for indexed pics) */ - uint8_t *index_buf_hist;/* index buffer historic */ - -} bitplane_decoder_t; - -/* create a new buffer and decde a byterun1 decoded buffer into it */ -static uint8_t *bitplane_decode_byterun1 (uint8_t *compressed, - int size_compressed, - int size_uncompressed) { - - /* BytRun1 decompression */ - int pixel_ptr = 0; - int i = 0; - int j = 0; - - uint8_t *uncompressed = xine_xmalloc( size_uncompressed ); - - while ( i < size_compressed && - pixel_ptr < size_uncompressed ) { - if( compressed[i] <= 127 ) { - j = compressed[i++]; - if( (i+j) > size_compressed ) { - free(uncompressed); - return NULL; - } - for( ; (j >= 0) && (pixel_ptr < size_uncompressed); j-- ) { - uncompressed[pixel_ptr++] = compressed[i++]; - } - } else if ( compressed[i] > 128 ) { - j = 256 - compressed[i++]; - if( i >= size_compressed ) { - free(uncompressed); - return NULL; - } - for( ; (j >= 0) && (pixel_ptr < size_uncompressed); j-- ) { - uncompressed[pixel_ptr++] = compressed[i]; - } - i++; - } - } - return uncompressed; -} - -/* create a new buffer with "normal" index or rgb numbers out of a bitplane */ -static void bitplane_decode_bitplane (uint8_t *bitplane_buffer, - uint8_t *index_buf, - int width, - int height, - int num_bitplanes, - int bytes_per_pixel ) { - - int rowsize = width / 8; - int pixel_ptr = 0; - int row_ptr = 0; - int palette_index = 0; - int i = 0; - int j = 0; - int row_i = 0; - int row_j = 0; - int palette_offset = 0; - int palette_index_rowsize = 0; - uint8_t color = 0; - uint8_t data = 0; - int bytes_per_pixel_8 = bytes_per_pixel * 8; - int rowsize_num_bitplanes = rowsize * num_bitplanes; - int width_bytes_per_pixel = width * bytes_per_pixel; - - for (i = 0; i < (height * width_bytes_per_pixel); index_buf[i++] = 0); - - /* decode Bitplanes to RGB/Index Numbers */ - for (row_ptr = 0; row_ptr < height; row_ptr++) { - - row_i = row_ptr * width_bytes_per_pixel; - row_j = row_ptr * rowsize_num_bitplanes; - - for (palette_index = 0; palette_index < num_bitplanes; palette_index++) { - - palette_offset = ((palette_index > 15) ? 2 : (palette_index > 7) ? 1 : 0); - color = bitplainoffeset[palette_index]; - palette_index_rowsize = palette_index * rowsize; - - for (pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { - i = row_i + - (pixel_ptr * bytes_per_pixel_8) + - palette_offset; - j = row_j + palette_index_rowsize + pixel_ptr; - - data = bitplane_buffer[j]; - - index_buf[i] += ((data & 0x80) ? color : 0); - i += bytes_per_pixel; - index_buf[i] += ((data & 0x40) ? color : 0); - i += bytes_per_pixel; - index_buf[i] += ((data & 0x20) ? color : 0); - i += bytes_per_pixel; - index_buf[i] += ((data & 0x10) ? color : 0); - i += bytes_per_pixel; - index_buf[i] += ((data & 0x08) ? color : 0); - i += bytes_per_pixel; - index_buf[i] += ((data & 0x04) ? color : 0); - i += bytes_per_pixel; - index_buf[i] += ((data & 0x02) ? color : 0); - i += bytes_per_pixel; - index_buf[i] += ((data & 0x01) ? color : 0); - } - } - } -} - -/* create Buffer decode HAM6 and HAM8 to YUV color */ -static void bitplane_decode_ham (uint8_t *ham_buffer, - yuv_planes_t *yuv_planes, - int width, - int height, - int num_bitplanes, - int bytes_per_pixel, - unsigned char *rgb_palette ) { - - uint8_t *ham_buffer_work = ham_buffer; - uint8_t *ham_buffer_end = &ham_buffer[(width * height)]; - uint8_t *yuv_ptr_y = yuv_planes->y; - uint8_t *yuv_ptr_u = yuv_planes->u; - uint8_t *yuv_ptr_v = yuv_planes->v; - int i = 0; - int j = 0; - uint8_t r = 0; - uint8_t g = 0; - uint8_t b = 0; - /* position of special HAM-Bits differs in HAM6 and HAM8, detect them */ - int hambits = num_bitplanes > 6 ? 6 : 4; - /* the other bits contain the real data, dreate a mask out of it */ - int maskbits = 8 - hambits; - int mask = ( 1 << hambits ) - 1; - - for(; ham_buffer_work < ham_buffer_end; j = *ham_buffer_work++) { - i = (j & mask); - switch ( j >> hambits ) { - case HAMBITS_CMAP: - /* Take colors from palette */ - r = rgb_palette[i * 4 + 0]; - g = rgb_palette[i * 4 + 1]; - b = rgb_palette[i * 4 + 2]; - break; - case HAMBITS_BLUE: - /* keep red and green and modify blue */ - b = i << maskbits; - b |= b >> hambits; - break; - case HAMBITS_RED: - /* keep green and blue and modify red */ - r = i << maskbits; - r |= r >> hambits; - break; - case HAMBITS_GREEN: - /* keep red and blue and modify green */ - g = i << maskbits; - g |= g >> hambits; - break; - default: - break; - } - *yuv_ptr_y++ = COMPUTE_Y(r, g, b); - *yuv_ptr_u++ = COMPUTE_U(r, g, b); - *yuv_ptr_v++ = COMPUTE_V(r, g, b); - } -} - -/* decoding method 3 */ -static void bitplane_sdelta_opt_3 (bitplane_decoder_t *this) { - - uint32_t rowsize = this->width / 16; - uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; - - uint32_t palette_index = 0; - uint32_t *deltadata = (uint32_t *)this->buf; - uint16_t *ptr = NULL; - uint16_t *planeptr = NULL; - uint16_t *picture_end = (uint16_t *)(&this->buf_uk[(rowsize_all_planes * 2 * this->height)]); - uint16_t *data = NULL; - uint16_t *data_end = (uint16_t *)(&this->buf[this->size]); - uint16_t *rowworkptr = NULL; - int16_t s = 0; - int16_t size = 0; - uint32_t pixel_ptr_bit = 0; - uint32_t row_ptr = 0; - uint32_t yuv_index = 0; - - /* Repeat for each plane */ - for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { - - planeptr = (uint16_t *)(&this->buf_uk[(palette_index * rowsize * 2)]); - /* data starts at beginn of delta-Buffer + offset of the first */ - /* 32 Bit long word in the buffer. The buffer starts with 8 */ - /* of this Offset, for every bitplane (max 8) one */ - data = (uint16_t *)(&this->buf[_X_BE_32(&deltadata[palette_index])]); - if( data != (uint16_t *)this->buf ) { - /* This 8 Pointers are followd by another 8 */ - ptr = (uint16_t *)(&this->buf[_X_BE_32(&deltadata[(palette_index+8)])]); - - /* in this case, I think big/little endian is not important ;-) */ - while( *data != 0xFFFF) { - row_ptr = 0; - size = _X_BE_16(data); - data++; - if( size >= 0 ) { - rowworkptr = planeptr + size; - pixel_ptr_bit = size * 16; - if( this->is_ham ) { - IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[pixel_ptr_bit], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_SHORT( &this->index_buf[pixel_ptr_bit], - &this->yuv_planes.y[pixel_ptr_bit], &this->yuv_planes.u[pixel_ptr_bit], - &this->yuv_planes.v[pixel_ptr_bit], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - data++; - } else { - size = 0 - size + 2; - rowworkptr = planeptr + size; - pixel_ptr_bit = size * 16; - s = _X_BE_16(data); - data++; - while( s--) { - if( this->is_ham ) { - IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[pixel_ptr_bit], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_SHORT( &this->index_buf[pixel_ptr_bit], - &this->yuv_planes.y[pixel_ptr_bit], &this->yuv_planes.u[pixel_ptr_bit], - &this->yuv_planes.v[pixel_ptr_bit], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - rowworkptr++; - data++; - } - } - - - - - size = _X_BE_16(ptr); - ptr++; - if (size < 0) { - for (s = size; s < 0; s++) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_SHORT( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - rowworkptr += rowsize_all_planes; - row_ptr++; - } - data++; - } - else { - for (s = 0; s < size; s++) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_SHORT( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - data++; - rowworkptr += rowsize_all_planes; - row_ptr++; - } - } - } - } - } -} - -/* decoding method 4 */ -static void bitplane_set_dlta_short (bitplane_decoder_t *this) { - - uint32_t rowsize = this->width / 16; - uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; - - uint32_t palette_index = 0; - uint32_t *deltadata = (uint32_t *)this->buf; - uint16_t *ptr = NULL; - uint16_t *planeptr = NULL; - uint16_t *picture_end = (uint16_t *)(&this->buf_uk[(rowsize_all_planes * 2 * this->height)]); - uint16_t *data = NULL; - uint16_t *data_end = (uint16_t *)(&this->buf[this->size]); - uint16_t *rowworkptr = NULL; - int16_t s = 0; - int16_t size = 0; - uint16_t pixel_ptr = 0; - uint32_t pixel_ptr_bit = 0; - uint32_t row_ptr = 0; - uint32_t yuv_index = 0; - - /* Repeat for each plane */ - for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { - - planeptr = (uint16_t *)(&this->buf_uk[(palette_index * rowsize * 2)]); - /* data starts at beginn of delta-Buffer + offset of the first */ - /* 32 Bit long word in the buffer. The buffer starts with 8 */ - /* of this Offset, for every bitplane (max 8) one */ - data = (uint16_t *)(&this->buf[_X_BE_32(&deltadata[palette_index])]); - if( data != (uint16_t *)this->buf ) { - /* This 8 Pointers are followd by another 8 */ - ptr = (uint16_t *)(&this->buf[_X_BE_32(&deltadata[(palette_index+8)])]); - - /* in this case, I think big/little endian is not important ;-) */ - while( *ptr != 0xFFFF) { - pixel_ptr = _X_BE_16(ptr); - pixel_ptr_bit = pixel_ptr * 16; - row_ptr = 0; - rowworkptr = planeptr + pixel_ptr; - ptr++; - size = _X_BE_16(ptr); - ptr++; - if (size < 0) { - for (s = size; s < 0; s++) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_SHORT( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - rowworkptr += rowsize_all_planes; - row_ptr++; - } - data++; - } else { - for (s = 0; s < size; s++) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_SHORT( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - data++; - rowworkptr += rowsize_all_planes; - row_ptr++; - } - } - } - } - } -} - -/* decoding method 5 */ -static void bitplane_dlta_5 (bitplane_decoder_t *this) { - - uint32_t rowsize = this->width / 8; - uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; - - uint32_t yuv_index = 0; - uint32_t delta_offset = 0; - uint32_t palette_index = 0; - uint32_t pixel_ptr = 0; - uint32_t pixel_ptr_bit = 0; - uint32_t row_ptr = 0; - uint32_t *deltadata = (uint32_t *)this->buf; - uint8_t *planeptr = NULL; - uint8_t *rowworkptr = NULL; - uint8_t *picture_end = this->buf_uk + (rowsize_all_planes * this->height); - uint8_t *data = NULL; - uint8_t *data_end = this->buf + this->size; - uint8_t op_count = 0; - uint8_t op = 0; - uint8_t count = 0; - - /* Repeat for each plane */ - for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { - - planeptr = &this->buf_uk[(palette_index * rowsize)]; - /* data starts at beginn of delta-Buffer + offset of the first */ - /* 32 Bit long word in the buffer. The buffer starts with 8 */ - /* of this Offset, for every bitplane (max 8) one */ - delta_offset = _X_BE_32(&deltadata[palette_index]); - - if (delta_offset > 0) { - data = this->buf + delta_offset; - for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { - rowworkptr = planeptr + pixel_ptr; - pixel_ptr_bit = pixel_ptr * 8; - row_ptr = 0; - /* execute ops */ - for( op_count = *data++; op_count; op_count--) { - op = *data++; - if (op & 0x80) { - /* Uniq ops */ - count = op & 0x7f; /* get count */ - while(count--) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_BYTE_SIMPLE(&this->index_buf[yuv_index], - *rowworkptr, *data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_BYTE( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - *rowworkptr, *data, bitplainoffeset[palette_index] ); - } - data++; - rowworkptr += rowsize_all_planes; - row_ptr++; - } - } else { - if (op == 0) { - /* Same ops */ - count = *data++; - while(count--) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_BYTE_SIMPLE(&this->index_buf[yuv_index], - *rowworkptr, *data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_BYTE( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - *rowworkptr, *data, bitplainoffeset[palette_index] ); - } - rowworkptr += rowsize_all_planes; - row_ptr++; - } - data++; - } else { - /* Skip ops */ - rowworkptr += (rowsize_all_planes * op); - row_ptr += op; - } - } - } - } - } - } -} - -/* decoding method 7 (short version) */ -static void bitplane_dlta_7_short (bitplane_decoder_t *this) { - - uint32_t rowsize = this->width / 16; - uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; - - uint32_t yuv_index = 0; - uint32_t opcode_offset = 0; - uint32_t data_offset = 0; - uint32_t palette_index = 0; - uint32_t pixel_ptr = 0; - uint32_t pixel_ptr_bit = 0; - uint32_t row_ptr = 0; - uint32_t *deltadata = (uint32_t *)this->buf; - uint8_t *planeptr = NULL; - uint16_t *rowworkptr = NULL; - uint16_t *picture_end = (uint16_t *)(&this->buf_uk[(rowsize_all_planes * 2 * this->height)]); - uint16_t *data = NULL; - uint16_t *data_end = (uint16_t *)(&this->buf[this->size]); - uint8_t *op_ptr = NULL; - uint8_t op_count = 0; - uint8_t op = 0; - uint8_t count = 0; - - /* Repeat for each plane */ - for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { - - planeptr = &this->buf_uk[(palette_index * rowsize * 2)]; - /* find opcode and data offset (up to 8 pointers, one for every bitplane */ - opcode_offset = _X_BE_32(&deltadata[palette_index]); - data_offset = _X_BE_32(&deltadata[palette_index + 8]); - - if (opcode_offset > 0 && data_offset > 0) { - data = (uint16_t *)(&this->buf[data_offset]); - op_ptr = this->buf + opcode_offset; - for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { - rowworkptr = (uint16_t *)(&planeptr[pixel_ptr * 2]); - pixel_ptr_bit = pixel_ptr * 16; - row_ptr = 0; - /* execute ops */ - for( op_count = *op_ptr++; op_count; op_count--) { - op = *op_ptr++; - if (op & 0x80) { - /* Uniq ops */ - count = op & 0x7f; /* get count */ - while(count--) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_SHORT( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - data++; - rowworkptr += rowsize_all_planes; - row_ptr++; - } - } else { - if (op == 0) { - /* Same ops */ - count = *op_ptr++; - while(count--) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_SHORT( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - rowworkptr += rowsize_all_planes; - row_ptr++; - } - data++; - } else { - /* Skip ops */ - rowworkptr += (rowsize_all_planes * op); - row_ptr += op; - } - } - } - } - } - } -} - -/* decoding method 7 (long version) */ -static void bitplane_dlta_7_long (bitplane_decoder_t *this) { - - uint32_t rowsize = this->width / 32; - uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; - - uint32_t yuv_index = 0; - uint32_t opcode_offset = 0; - uint32_t data_offset = 0; - uint32_t palette_index = 0; - uint32_t pixel_ptr = 0; - uint32_t pixel_ptr_bit = 0; - uint32_t row_ptr = 0; - uint32_t *deltadata = (uint32_t *)this->buf; - uint8_t *planeptr = NULL; - uint32_t *rowworkptr = NULL; - uint32_t *picture_end = (uint32_t *)(&this->buf_uk[(rowsize_all_planes * 4 * this->height)]); - uint32_t *data = NULL; - uint32_t *data_end = (uint32_t *)(&this->buf[this->size]); - uint8_t *op_ptr = NULL; - uint8_t op_count = 0; - uint8_t op = 0; - uint8_t count = 0; - - /* Repeat for each plane */ - for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { - planeptr = &this->buf_uk[(palette_index * rowsize * 4)]; - /* find opcode and data offset (up to 8 pointers, one for every bitplane */ - opcode_offset = _X_BE_32(&deltadata[palette_index]); - data_offset = _X_BE_32(&deltadata[palette_index + 8]); - - if (opcode_offset > 0 && data_offset > 0) { - data = (uint32_t *)(&this->buf[data_offset]); - op_ptr = this->buf + opcode_offset; - for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { - rowworkptr = (uint32_t *)(&planeptr[pixel_ptr * 4]); - pixel_ptr_bit = pixel_ptr * 32; - row_ptr = 0; - /* execute ops */ - for( op_count = *op_ptr++; op_count; op_count--) { - op = *op_ptr++; - if (op & 0x80) { - /* Uniq ops */ - count = op & 0x7f; /* get count */ - while(count--) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_LONG_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_LONG( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - data++; - rowworkptr += rowsize_all_planes; - row_ptr++; - } - } else { - if (op == 0) { - /* Same ops */ - count = *op_ptr++; - while(count--) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_LONG_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_LONG( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - rowworkptr += rowsize_all_planes; - row_ptr++; - } - data++; - } else { - /* Skip ops */ - rowworkptr += (rowsize_all_planes * op); - row_ptr += op; - } - } - } - } - } - } -} - -/* decoding method 8 short */ -static void bitplane_dlta_8_short (bitplane_decoder_t *this) { - - uint32_t rowsize = this->width / 16; - uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; - - uint32_t yuv_index = 0; - uint32_t delta_offset = 0; - uint32_t palette_index = 0; - uint32_t pixel_ptr = 0; - uint32_t row_ptr = 0; - uint32_t pixel_ptr_bit = 0; - uint32_t *deltadata = (uint32_t *)this->buf; - uint16_t *planeptr = NULL; - uint16_t *rowworkptr = NULL; - uint16_t *picture_end = (uint16_t *)(&this->buf_uk[(rowsize_all_planes * 2 * this->height)]); - uint16_t *data = NULL; - uint16_t *data_end = (uint16_t *)(&this->buf[this->size]); - uint16_t op_count = 0; - uint16_t op = 0; - uint16_t count = 0; - - /* Repeat for each plane */ - for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { - - planeptr = (uint16_t *)(&this->buf_uk[(palette_index * rowsize * 2)]); - /* data starts at beginn of delta-Buffer + offset of the first */ - /* 32 Bit long word in the buffer. The buffer starts with 8 */ - /* of this Offset, for every bitplane (max 8) one */ - delta_offset = _X_BE_32(&deltadata[palette_index]); - - if (delta_offset > 0) { - data = (uint16_t *)(&this->buf[delta_offset]); - for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { - rowworkptr = planeptr + pixel_ptr; - pixel_ptr_bit = pixel_ptr * 16; - row_ptr = 0; - /* execute ops */ - op_count = _X_BE_16(data); - data++; - for( ; op_count; op_count--) { - op = _X_BE_16(data); - data++; - if (op & 0x8000) { - /* Uniq ops */ - count = op & 0x7fff; /* get count */ - while(count--) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_SHORT( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - data++; - rowworkptr += rowsize_all_planes; - row_ptr++; - } - } else { - if (op == 0) { - /* Same ops */ - count = _X_BE_16(data); - data++; - while(count--) { - if (data > data_end || rowworkptr > picture_end) - return; - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_SHORT( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - rowworkptr += rowsize_all_planes; - row_ptr++; - } - data++; - } else { - /* Skip ops */ - rowworkptr += (rowsize_all_planes * op); - row_ptr += op; - } - } - } - } - } - } -} - -/* decoding method 8 long */ -static void bitplane_dlta_8_long (bitplane_decoder_t *this) { - - uint32_t rowsize = this->width / 32; - uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; - - uint32_t yuv_index = 0; - uint32_t delta_offset = 0; - uint32_t palette_index = 0; - uint32_t pixel_ptr = 0; - uint32_t pixel_ptr_bit = 0; - uint32_t row_ptr = 0; - uint32_t *deltadata = (uint32_t *)this->buf; - uint32_t *planeptr = NULL; - uint32_t *rowworkptr = NULL; - uint32_t *picture_end = (uint32_t *)(&this->buf_uk[(rowsize_all_planes * 4 * this->height)]); - uint32_t *data = NULL; - uint32_t *data_end = (uint32_t *)(&this->buf[this->size]); - uint32_t op_count = 0; - uint32_t op = 0; - uint32_t count = 0; - - /* Repeat for each plane */ - for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { - - planeptr = (uint32_t *)(&this->buf_uk[(palette_index * rowsize * 4)]); - /* data starts at beginn of delta-Buffer + offset of the first */ - /* 32 Bit long word in the buffer. The buffer starts with 8 */ - /* of this Offset, for every bitplane (max 8) one */ - delta_offset = _X_BE_32(&deltadata[palette_index]); - - if (delta_offset > 0) { - data = (uint32_t *)(&this->buf[delta_offset]); - for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { - rowworkptr = planeptr + pixel_ptr; - pixel_ptr_bit = pixel_ptr * 32; - row_ptr = 0; - /* execute ops */ - op_count = _X_BE_32(data); - data++; - for( ; op_count; op_count--) { - op = _X_BE_32(data); - data++; - if (op & 0x80000000) { - /* Uniq ops */ - count = op & 0x7fffffff; /* get count */ - while(count--) { - if (data <= data_end || rowworkptr <= picture_end) { - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_LONG_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_LONG( &this->index_buf[((row_ptr * this->width) + pixel_ptr_bit)], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - } - data++; - rowworkptr += rowsize_all_planes; - row_ptr++; - } - } else { - if (op == 0) { - /* Same ops */ - count = _X_BE_32(data); - data++; - while(count--) { - if (data <= data_end && rowworkptr <= picture_end) { - yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); - if( this->is_ham ) { - IFF_REPLACE_LONG_SIMPLE(&this->index_buf[yuv_index], - rowworkptr, data, bitplainoffeset[palette_index] ); - } else { - IFF_REPLACE_LONG( &this->index_buf[yuv_index], - &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], - &this->yuv_planes.v[yuv_index], this->yuv_palette, - rowworkptr, data, bitplainoffeset[palette_index] ); - } - } - rowworkptr += rowsize_all_planes; - row_ptr++; - } - data++; - } else { - /* Skip ops */ - rowworkptr += (rowsize_all_planes * op); - row_ptr += op; - } - } - } - } - } - } -/* bitplane_decode_bitplane(this->buf_uk, this->index_buf, this->width, this->height, this->num_bitplanes, 1);*/ -} - -static void bitplane_decode_data (video_decoder_t *this_gen, - buf_element_t *buf) { - - bitplane_decoder_t *this = (bitplane_decoder_t *) this_gen; - xine_bmiheader *bih = 0; - palette_entry_t *palette = 0; - AnimHeader *anhd = NULL; - int i = 0; - int j = 0; - int buf_ptr = 0; - unsigned char r = 0; - unsigned char g = 0; - unsigned char b = 0; - uint8_t *buf_exchange = NULL; - - vo_frame_t *img = 0; /* video out frame */ - - /* a video decoder does not care about this flag (?) */ - if (buf->decoder_flags & BUF_FLAG_PREVIEW) - return; - - if ((buf->decoder_flags & BUF_FLAG_SPECIAL) && - (buf->decoder_info[1] == BUF_SPECIAL_PALETTE)) { - palette = (palette_entry_t *)buf->decoder_info_ptr[2]; - - for (i = 0; i < buf->decoder_info[2]; i++) { - this->yuv_palette[i * 4 + 0] = - COMPUTE_Y(palette[i].r, palette[i].g, palette[i].b); - this->yuv_palette[i * 4 + 1] = - COMPUTE_U(palette[i].r, palette[i].g, palette[i].b); - this->yuv_palette[i * 4 + 2] = - COMPUTE_V(palette[i].r, palette[i].g, palette[i].b); - this->rgb_palette[i * 4 + 0] = palette[i].r; - this->rgb_palette[i * 4 + 1] = palette[i].g; - this->rgb_palette[i * 4 + 2] = palette[i].b; - } - - /* EHB Pictures not allways contain all 64 colors, sometimes only */ - /* the first 32 are included and sometimes all 64 colors are provide,*/ - /* but second 32 are only stupid dirt, so recalculate them */ - if (((this->num_bitplanes == 6) && - (buf->decoder_info[2] == 32)) || - (this->camg_mode & CAMG_EHB)) { - for (i = 32; i < 64; i++) { - this->rgb_palette[i * 4 + 0] = palette[(i-32)].r / 2; - this->rgb_palette[i * 4 + 1] = palette[(i-32)].g / 2; - this->rgb_palette[i * 4 + 2] = palette[(i-32)].b / 2; - this->yuv_palette[i * 4 + 0] = - COMPUTE_Y(this->rgb_palette[i*4+0], this->rgb_palette[i*4+1], this->rgb_palette[i*4+2]); - this->yuv_palette[i * 4 + 1] = - COMPUTE_U(this->rgb_palette[i*4+0], this->rgb_palette[i*4+1], this->rgb_palette[i*4+2]); - this->yuv_palette[i * 4 + 2] = - COMPUTE_V(this->rgb_palette[i*4+0], this->rgb_palette[i*4+1], this->rgb_palette[i*4+2]); - } - } - - return; - } - - if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ - (this->stream->video_out->open) (this->stream->video_out, this->stream); - - bih = (xine_bmiheader *) buf->content; - this->width = (bih->biWidth + 15) & ~0x0f; - this->height = bih->biHeight; - this->num_pixel = this->width * this->height; - this->ratio = (double)this->width/(double)this->height; - this->video_step = buf->decoder_info[1]; - /* Palette based Formates use up to 8 Bit per pixel, always use 8 Bit if less */ - this->bytes_per_pixel = (bih->biBitCount + 1) / 8; - if( this->bytes_per_pixel < 1 ) - this->bytes_per_pixel = 1; - - /* New Buffer for indexes (palette based formats) */ - this->index_buf = xine_xcalloc( this->num_pixel, this->bytes_per_pixel ); - this->index_buf_hist = xine_xcalloc( this->num_pixel, this->bytes_per_pixel ); - - this->num_bitplanes = bih->biPlanes; - this->camg_mode = bih->biCompression; - if( this->camg_mode & CAMG_HAM ) - this->is_ham = 1; - else - this->is_ham = 0; - - if( buf->decoder_info[2] != buf->decoder_info[3] && - buf->decoder_info[3] > 0 ) { - this->ratio *= buf->decoder_info[2]; - this->ratio /= buf->decoder_info[3]; - } - - if( (bih->biCompression & CAMG_HIRES) && - !(bih->biCompression & CAMG_LACE) ) { - if( (buf->decoder_info[2] * 16) > (buf->decoder_info[3] * 10) ) - this->ratio /= 2.0; - } - - if( !(bih->biCompression & CAMG_HIRES) && - (bih->biCompression & CAMG_LACE) ) { - if( (buf->decoder_info[2] * 10) < (buf->decoder_info[3] * 16) ) - this->ratio *= 2.0; - } - - free (this->buf); - this->bufsize = VIDEOBUFSIZE; - this->buf = xine_xmalloc(this->bufsize); - this->size = 0; - this->framenumber = 0; - - init_yuv_planes(&this->yuv_planes, this->width, this->height); - init_yuv_planes(&this->yuv_planes_hist, this->width, this->height); - - (this->stream->video_out->open) (this->stream->video_out, this->stream); - this->decoder_ok = 1; - - /* load the stream/meta info */ - switch( buf->type ) { - case BUF_VIDEO_BITPLANE: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Uncompressed bitplane"); - break; - case BUF_VIDEO_BITPLANE_BR1: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "ByteRun1 bitplane"); - break; - default: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Unknown bitplane"); - break; - } - - return; - } else if (this->decoder_ok) { - - this->skipframes = 0; - this->framenumber++; - if (this->size + buf->size > this->bufsize) { - this->bufsize = this->size + 2 * buf->size; - this->buf = realloc (this->buf, this->bufsize); - } - - xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); - - this->size += buf->size; - - if (buf->decoder_flags & BUF_FLAG_FRAMERATE) - this->video_step = buf->decoder_info[0]; - - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { - - img = this->stream->video_out->get_frame (this->stream->video_out, - this->width, this->height, - this->ratio, XINE_IMGFMT_YUY2, - VO_BOTH_FIELDS); - - img->duration = this->video_step; - img->pts = buf->pts; - img->bad_frame = 0; - anhd = (AnimHeader *)(buf->decoder_info_ptr[0]); - - if( (this->buf_uk == NULL) || - (anhd == NULL) || - (anhd->operation == IFF_ANHD_ILBM) ) { - - /* iterate through each row */ - buf_ptr = 0; - this->size_uk = (((this->num_pixel) / 8) * this->num_bitplanes); - - if( this->buf_uk_hist != NULL ) - xine_fast_memcpy (this->buf_uk_hist, this->buf_uk, this->size_uk); - switch( buf->type ) { - case BUF_VIDEO_BITPLANE: - /* uncompressed Buffer, set decoded_buf pointer direct to input stream */ - if( this->buf_uk == NULL ) - this->buf_uk = xine_xmalloc( (this->size) ); - xine_fast_memcpy (this->buf_uk, this->buf, this->size); - break; - case BUF_VIDEO_BITPLANE_BR1: - /* create Buffer for decompressed bitmap */ - this->buf_uk = bitplane_decode_byterun1( - this->buf, /* compressed buffer */ - this->size, /* size of compressed data */ - this->size_uk ); /* size of uncompressed data */ - - if( this->buf_uk == NULL ) { - xine_log(this->stream->xine, XINE_LOG_MSG, - _("bitplane: error doing ByteRun1 decompression\n")); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); - return; - } - /* set pointer to decompressed Buffer */ - break; - default: - break; - } - bitplane_decode_bitplane( this->buf_uk, /* bitplane buffer */ - this->index_buf, /* index buffer */ - this->width, /* width */ - this->height, /* hight */ - this->num_bitplanes, /* number bitplanes */ - this->bytes_per_pixel); /* used Bytes per pixel */ - - if ((this->bytes_per_pixel == 1) && - (this->is_ham == 0) ) { - buf_exchange = this->index_buf; - for (i = 0; i < (this->height * this->width); i++) { - j = *buf_exchange++ * 4; - this->yuv_planes.y[i] = this->yuv_palette[j++]; - this->yuv_planes.u[i] = this->yuv_palette[j++]; - this->yuv_planes.v[i] = this->yuv_palette[j]; - } - } - if( this->buf_uk_hist == NULL ) { - this->buf_uk_hist = xine_xmalloc( (this->size_uk) ); - xine_fast_memcpy (this->buf_uk_hist, this->buf_uk, this->size_uk); - xine_fast_memcpy (this->index_buf_hist, this->index_buf, - (this->num_pixel * this->bytes_per_pixel)); - xine_fast_memcpy (this->yuv_planes_hist.y, this->yuv_planes.y, (this->num_pixel)); - xine_fast_memcpy (this->yuv_planes_hist.u, this->yuv_planes.u, (this->num_pixel)); - xine_fast_memcpy (this->yuv_planes_hist.v, this->yuv_planes.v, (this->num_pixel)); - } - } else { - /* when no start-picture is given, create a empty one */ - if( this->buf_uk_hist == NULL ) { - this->size_uk = (((this->num_pixel) / 8) * this->num_bitplanes); - this->buf_uk = xine_xmalloc( (this->size_uk) ); - this->buf_uk_hist = xine_xmalloc( (this->size_uk) ); - for (i = 0; i < this->size_uk; i++) { - this->buf_uk[i] = 0; - this->buf_uk_hist[i] = 0; - } - } - if( this->index_buf == NULL ) { - this->index_buf = xine_xcalloc( this->num_pixel, this->bytes_per_pixel ); - this->index_buf_hist = xine_xcalloc( this->num_pixel, this->bytes_per_pixel ); - for (i = 0; i < (this->num_pixel * this->bytes_per_pixel); i++) { - this->index_buf[i] = 0; - this->index_buf_hist[i] = 0; - } - } - - switch( anhd->operation ) { - /* also known as IFF-ANIM OPT1 (never seen in real world) */ - case IFF_ANHD_XOR: - xine_log(this->stream->xine, XINE_LOG_MSG, - _("bitplane: Anim Opt 1 is not supported at the moment\n")); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); - return; - break; - /* also known as IFF-ANIM OPT2 (never seen in real world) */ - case IFF_ANHD_LDELTA: - xine_log(this->stream->xine, XINE_LOG_MSG, - _("bitplane: Anim Opt 2 is not supported at the moment\n")); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); - return; - break; - /* also known as IFF-ANIM OPT3 */ - case IFF_ANHD_SDELTA: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT3"); - bitplane_sdelta_opt_3 ( this ); - return; - break; - /* also known as IFF-ANIM OPT4 (never seen in real world) */ - case IFF_ANHD_SLDELTA: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT4 (SLDELTA)"); - bitplane_set_dlta_short ( this ); - break; - /* also known as IFF-ANIM OPT5 */ - case IFF_ANHD_BVDELTA: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT5 (BVDELTA)"); - bitplane_dlta_5(this); - break; - /* IFF-ANIM OPT6 is exactly the same as OPT5, but for stereo-displays */ - /* first picture is on the left display, second on the right, third on */ - /* the left, forth on right, ... Only display left picture on mono display*/ - case IFF_ANHD_STEREOO5: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT6 (BVDELTA STEREO)"); - bitplane_dlta_5(this); - if( this->framenumber % 2 == 0 ) - this->skipframes = 1; - return; - break; - case IFF_ANHD_OPT7: - if(anhd->bits == 0) { - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT7 (SHORT)"); - bitplane_dlta_7_short(this); - } else { - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT7 (LONG)"); - bitplane_dlta_7_long(this); - } - break; - case IFF_ANHD_OPT8: - if(anhd->bits == 0) { - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT8 (SHORT)"); - bitplane_dlta_8_short(this); - } else { - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT8 (LONG)"); - bitplane_dlta_8_long(this); - } - break; - case IFF_ANHD_ASCIIJ: - xine_log(this->stream->xine, XINE_LOG_MSG, - _("bitplane: Anim ASCIIJ is not supported at the moment\n")); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); - return; - break; - default: - xine_log(this->stream->xine, XINE_LOG_MSG, - _("bitplane: This anim-type is not supported at the moment\n")); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); - return; - break; - } - /* change old bitmap buffer (which now is the new one) with new buffer */ - buf_exchange = this->buf_uk; - this->buf_uk = this->buf_uk_hist; - this->buf_uk_hist = buf_exchange; - /* do the same with the index buffer */ - buf_exchange = this->index_buf; - this->index_buf = this->index_buf_hist; - this->index_buf_hist = buf_exchange; - /* and also with yuv buffer */ - buf_exchange = this->yuv_planes.y; - this->yuv_planes.y = this->yuv_planes_hist.y; - this->yuv_planes_hist.y = buf_exchange; - buf_exchange = this->yuv_planes.u; - this->yuv_planes.u = this->yuv_planes_hist.u; - this->yuv_planes_hist.u = buf_exchange; - buf_exchange = this->yuv_planes.v; - this->yuv_planes.v = this->yuv_planes_hist.v; - this->yuv_planes_hist.v = buf_exchange; - } - - if( this->skipframes == 0 ) { - switch (this->bytes_per_pixel) { - case 1: - /* HAM-pictrues need special handling */ - if( this->is_ham ) { - /* Decode HAM-Pictures to YUV */ - bitplane_decode_ham( this->index_buf, /* HAM-bitplane buffer */ - &(this->yuv_planes), /* YUV buffer */ - this->width, /* width */ - this->height, /* hight */ - this->num_bitplanes, /* number bitplanes */ - this->bytes_per_pixel, /* used Bytes per pixel */ - this->rgb_palette); /* Palette (RGB) */ - } - break; - case 3: - buf_exchange = this->index_buf; - for (i = 0; i < (this->height * this->width); i++) { - r = *buf_exchange++; - g = *buf_exchange++; - b = *buf_exchange++; - - this->yuv_planes.y[i] = COMPUTE_Y(r, g, b); - this->yuv_planes.u[i] = COMPUTE_U(r, g, b); - this->yuv_planes.v[i] = COMPUTE_V(r, g, b); - } - break; - default: - break; - } - - yuv444_to_yuy2(&this->yuv_planes, img->base[0], img->pitches[0]); - - img->draw(img, this->stream); - } - img->free(img); - - this->size = 0; - if ( buf->decoder_info[1] > 90000 ) - xine_usec_sleep(buf->decoder_info[1]); - } - } -} - -/* - * This function is called when xine needs to flush the system. Not - * sure when or if this is used or even if it needs to do anything. - */ -static void bitplane_flush (video_decoder_t *this_gen) { -} - -/* - * This function resets the video decoder. - */ -static void bitplane_reset (video_decoder_t *this_gen) { - bitplane_decoder_t *this = (bitplane_decoder_t *) this_gen; - - this->size = 0; -} - -static void bitplane_discontinuity (video_decoder_t *this_gen) { -} - -/* - * This function frees the video decoder instance allocated to the decoder. - */ -static void bitplane_dispose (video_decoder_t *this_gen) { - bitplane_decoder_t *this = (bitplane_decoder_t *) this_gen; - - free (this->buf); - free (this->buf_uk); - free (this->buf_uk_hist); - free (this->index_buf); - free (this->index_buf_hist); - free (this->index_buf); - - if (this->decoder_ok) { - this->decoder_ok = 0; - this->stream->video_out->close(this->stream->video_out, this->stream); - } - - free (this_gen); -} - -static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { - - bitplane_decoder_t *this = (bitplane_decoder_t *) xine_xmalloc (sizeof (bitplane_decoder_t)); - - this->video_decoder.decode_data = bitplane_decode_data; - this->video_decoder.flush = bitplane_flush; - this->video_decoder.reset = bitplane_reset; - this->video_decoder.discontinuity = bitplane_discontinuity; - this->video_decoder.dispose = bitplane_dispose; - this->size = 0; - - this->stream = stream; - this->class = (bitplane_class_t *) class_gen; - - this->decoder_ok = 0; - this->buf = NULL; - this->buf_uk = NULL; - this->index_buf = NULL; - this->index_buf = NULL; - - return &this->video_decoder; -} - -static void *init_plugin (xine_t *xine, void *data) { - - bitplane_class_t *this = (bitplane_class_t *) xine_xmalloc (sizeof (bitplane_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "bitplane"; - this->decoder_class.description = N_("Raw bitplane video decoder plugin"); - this->decoder_class.dispose = default_video_decoder_class_dispose; - - return this; -} - -/* - * exported plugin catalog entry - */ - -static const uint32_t video_types[] = { - BUF_VIDEO_BITPLANE, - BUF_VIDEO_BITPLANE_BR1, - 0 -}; - -static const decoder_info_t dec_info_video = { - video_types, /* supported types */ - 1 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_VIDEO_DECODER, 19, "bitplane", XINE_VERSION_CODE, &dec_info_video, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libxinevdec/foovideo.c b/src/libxinevdec/foovideo.c deleted file mode 100644 index 49c63422c..000000000 --- a/src/libxinevdec/foovideo.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (C) 2000-2003 the xine project - * - * This file is part of xine, a free video player. - * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * foovideo.c: This is a reference video decoder for the xine multimedia - * player. It really works too! It will output frames of packed YUY2 data - * where each byte in the map is the same value, which is 3 larger than the - * value from the last frame. This creates a slowly rotating solid color - * frame when the frames are played in succession. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "bswap.h" - -#define VIDEOBUFSIZE 128*1024 - -typedef struct { - video_decoder_class_t decoder_class; -} foovideo_class_t; - -typedef struct foovideo_decoder_s { - video_decoder_t video_decoder; /* parent video decoder structure */ - - foovideo_class_t *class; - xine_stream_t *stream; - - /* these are traditional variables in a video decoder object */ - uint64_t video_step; /* frame duration in pts units */ - int decoder_ok; /* current decoder status */ - int skipframes; - - unsigned char *buf; /* the accumulated buffer data */ - int bufsize; /* the maximum size of buf */ - int size; /* the current size of buf */ - - int width; /* the width of a video frame */ - int height; /* the height of a video frame */ - double ratio; /* the width to height ratio */ - - /* these are variables exclusive to the foo video decoder */ - unsigned char current_yuv_byte; - -} foovideo_decoder_t; - -/************************************************************************** - * foovideo specific decode functions - *************************************************************************/ - -/************************************************************************** - * xine video plugin functions - *************************************************************************/ - -/* - * This function receives a buffer of data from the demuxer layer and - * figures out how to handle it based on its header flags. - */ -static void foovideo_decode_data (video_decoder_t *this_gen, - buf_element_t *buf) { - - foovideo_decoder_t *this = (foovideo_decoder_t *) this_gen; - xine_bmiheader *bih; - - vo_frame_t *img; /* video out frame */ - - /* a video decoder does not care about this flag (?) */ - if (buf->decoder_flags & BUF_FLAG_PREVIEW) - return; - - if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { - this->video_step = buf->decoder_info[0]; - _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step); - } - - if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ - (this->stream->video_out->open) (this->stream->video_out, this->stream); - - free(this->buf); - - bih = (xine_bmiheader *) buf->content; - this->width = bih->biWidth; - this->height = bih->biHeight; - this->ratio = (double)this->width/(double)this->height; - - if (this->buf) - free (this->buf); - this->bufsize = VIDEOBUFSIZE; - this->buf = malloc(this->bufsize); - this->size = 0; - - /* take this opportunity to load the stream/meta info */ - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "foovideo"); - - /* do anything else relating to initializing this decoder */ - this->current_yuv_byte = 0; - - this->decoder_ok = 1; - - return; - } else if (this->decoder_ok) { - - if (this->size + buf->size > this->bufsize) { - this->bufsize = this->size + 2 * buf->size; - this->buf = realloc (this->buf, this->bufsize); - } - - xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); - - this->size += buf->size; - - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { - - img = this->stream->video_out->get_frame (this->stream->video_out, - this->width, this->height, - this->ratio, - XINE_IMGFMT_YUY2, VO_BOTH_FIELDS); - - img->duration = this->video_step; - img->pts = buf->pts; - img->bad_frame = 0; - - memset(img->base[0], this->current_yuv_byte, - this->width * this->height * 2); - this->current_yuv_byte += 3; - - img->draw(img, this->stream); - img->free(img); - - this->size = 0; - } - } -} - -/* - * This function is called when xine needs to flush the system. - */ -static void foovideo_flush (video_decoder_t *this_gen) { -} - -/* - * This function resets the video decoder. - */ -static void foovideo_reset (video_decoder_t *this_gen) { - foovideo_decoder_t *this = (foovideo_decoder_t *) this_gen; - - this->size = 0; -} - -/* - * The decoder should forget any stored pts values here. - */ -static void foovideo_discontinuity (video_decoder_t *this_gen) { - foovideo_decoder_t *this = (foovideo_decoder_t *) this_gen; - -} - -/* - * This function frees the video decoder instance allocated to the decoder. - */ -static void foovideo_dispose (video_decoder_t *this_gen) { - - foovideo_decoder_t *this = (foovideo_decoder_t *) this_gen; - - free (this->buf); - - if (this->decoder_ok) { - this->decoder_ok = 0; - this->stream->video_out->close(this->stream->video_out, this->stream); - } - - free (this_gen); -} - -/* - * This function allocates, initializes, and returns a private video - * decoder structure. - */ -static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { - - foovideo_decoder_t *this ; - - this = (foovideo_decoder_t *) xine_xmalloc (sizeof (foovideo_decoder_t)); - - this->video_decoder.decode_data = foovideo_decode_data; - this->video_decoder.flush = foovideo_flush; - this->video_decoder.reset = foovideo_reset; - this->video_decoder.discontinuity = foovideo_discontinuity; - this->video_decoder.dispose = foovideo_dispose; - this->size = 0; - - this->stream = stream; - this->class = (foovideo_class_t *) class_gen; - - this->decoder_ok = 0; - this->buf = NULL; - - return &this->video_decoder; -} - -/* - * This function frees the video decoder class and any other memory that was - * allocated. - */ -static void dispose_class (video_decoder_class_t *this) { - free (this); -} - -/* - * This function allocates a private video decoder class and initializes - * the class's member functions. - */ -static void *init_plugin (xine_t *xine, void *data) { - - foovideo_class_t *this; - - this = (foovideo_class_t *) xine_xmalloc (sizeof (foovideo_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "foovideo"; - this->decoder_class.description = N_("foovideo: reference xine video decoder plugin"); - this->decoder_class.dispose = dispose_class; - - return this; -} - -/* - * This is a list of all of the internal xine video buffer types that - * this decoder is able to handle. Check src/xine-engine/buffer.h for a - * list of valid buffer types (and add a new one if the one you need does - * not exist). Terminate the list with a 0. - */ -static const uint32_t video_types[] = { - /* BUF_VIDEO_FOOVIDEO, */ - BUF_VIDEO_VQA, - BUF_VIDEO_SORENSON_V3, - 0 -}; - -/* - * This data structure combines the list of supported xine buffer types and - * the priority that the plugin should be given with respect to other - * plugins that handle the same buffer type. A plugin with priority (n+1) - * will be used instead of a plugin with priority (n). - */ -static const decoder_info_t dec_info_video = { - video_types, /* supported types */ - 5 /* priority */ -}; - -/* - * The plugin catalog entry. This is the only information that this plugin - * will export to the public. - */ -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* { type, API, "name", version, special_info, init_function } */ - { PLUGIN_VIDEO_DECODER, 19, "foovideo", XINE_VERSION_CODE, &dec_info_video, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libxinevdec/gdkpixbuf.c b/src/libxinevdec/gdkpixbuf.c deleted file mode 100644 index 28c9c77c7..000000000 --- a/src/libxinevdec/gdkpixbuf.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright (C) 2006 the xine project - * - * This file is part of xine, a free video player. - * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * a gdk-pixbuf-based image video decoder - */ - - -#include -#include -#include -#include -#include -#include -#include - -#define LOG_MODULE "gdkpixbuf_video_decoder" -#define LOG_VERBOSE -/* -#define LOG -*/ - -#include -#include -#include -#include -#include "bswap.h" - -#include - -typedef struct { - video_decoder_class_t decoder_class; - - /* - * private variables - */ - -} image_class_t; - - -typedef struct image_decoder_s { - video_decoder_t video_decoder; - - image_class_t *cls; - - xine_stream_t *stream; - int video_open; - - GdkPixbufLoader *loader; - -} image_decoder_t; - - -static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { - image_decoder_t *this = (image_decoder_t *) this_gen; - GError *error = NULL; - - if (!this->video_open) { - lprintf("opening video\n"); - (this->stream->video_out->open) (this->stream->video_out, this->stream); - this->video_open = 1; - } - - if (this->loader == NULL) { - this->loader = gdk_pixbuf_loader_new (); - } - - if (gdk_pixbuf_loader_write (this->loader, buf->mem, buf->size, &error) == FALSE) { - lprintf("error loading image: %s\n", error->message); - g_error_free (error); - gdk_pixbuf_loader_close (this->loader, NULL); - g_object_unref (G_OBJECT (this->loader)); - this->loader = NULL; - return; - } - - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { - GdkPixbuf *pixbuf; - int width, height, x, y, rowstride, n_channels, i; - guchar *img_buf; - yuv_planes_t yuv_planes; - vo_frame_t *img; - - /* - * this->image -> rgb data - */ - if (gdk_pixbuf_loader_close (this->loader, &error) == FALSE) { - lprintf("error loading image: %s\n", error->message); - g_error_free (error); - g_object_unref (G_OBJECT (this->loader)); - this->loader = NULL; - return; - } - - pixbuf = gdk_pixbuf_loader_get_pixbuf (this->loader); - if (pixbuf != NULL) - g_object_ref (G_OBJECT (pixbuf)); - g_object_unref (this->loader); - this->loader = NULL; - - if (pixbuf == NULL) { - lprintf("error loading image\n"); - return; - } - - width = gdk_pixbuf_get_width (pixbuf) & ~1; /* must be even for init_yuv_planes */ - height = gdk_pixbuf_get_height (pixbuf); - img_buf = gdk_pixbuf_get_pixels (pixbuf); - - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, width); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, height); - - lprintf("image loaded successfully\n"); - - /* - * rgb data -> yuv_planes - */ - init_yuv_planes(&yuv_planes, width, height); - - n_channels = gdk_pixbuf_get_n_channels (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - i = 0; - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - guchar *p; - p = img_buf + y * rowstride + x * n_channels; - - yuv_planes.y[i] = COMPUTE_Y (p[0], p[1], p[2]); - yuv_planes.u[i] = COMPUTE_U (p[0], p[1], p[2]); - yuv_planes.v[i] = COMPUTE_V (p[0], p[1], p[2]); - - i++; - } - } - gdk_pixbuf_unref (pixbuf); - - /* - * alloc and draw video frame - */ - img = this->stream->video_out->get_frame (this->stream->video_out, width, - height, (double)width/(double)height, - XINE_IMGFMT_YUY2, - VO_BOTH_FIELDS); - img->pts = buf->pts; - img->duration = 3600; - img->bad_frame = 0; - - yuv444_to_yuy2(&yuv_planes, img->base[0], img->pitches[0]); - free_yuv_planes(&yuv_planes); - - _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, img->duration); - - img->draw(img, this->stream); - img->free(img); - } -} - - -static void image_flush (video_decoder_t *this_gen) { - /* image_decoder_t *this = (image_decoder_t *) this_gen; */ - - /* - * flush out any frames that are still stored in the decoder - */ -} - - -static void image_reset (video_decoder_t *this_gen) { - image_decoder_t *this = (image_decoder_t *) this_gen; - - /* - * reset decoder after engine flush (prepare for new - * video data not related to recently decoded data) - */ - - if (this->loader != NULL) { - gdk_pixbuf_loader_close (this->loader, NULL); - g_object_unref (G_OBJECT (this->loader)); - this->loader = NULL; - } -} - - -static void image_discontinuity (video_decoder_t *this_gen) { - /* image_decoder_t *this = (image_decoder_t *) this_gen; */ - - /* - * a time reference discontinuity has happened. - * that is, it must forget any currently held pts value - */ -} - -static void image_dispose (video_decoder_t *this_gen) { - image_decoder_t *this = (image_decoder_t *) this_gen; - - if (this->video_open) { - lprintf("closing video\n"); - - this->stream->video_out->close(this->stream->video_out, this->stream); - this->video_open = 0; - } - - if (this->loader != NULL) { - gdk_pixbuf_loader_close (this->loader, NULL); - g_object_unref (G_OBJECT (this->loader)); - this->loader = NULL; - } - - lprintf("closed\n"); - free (this); -} - - -static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, - xine_stream_t *stream) { - - image_class_t *cls = (image_class_t *) class_gen; - image_decoder_t *this; - - lprintf("opened\n"); - - g_type_init (); - - this = (image_decoder_t *) xine_xmalloc (sizeof (image_decoder_t)); - - this->video_decoder.decode_data = image_decode_data; - this->video_decoder.flush = image_flush; - this->video_decoder.reset = image_reset; - this->video_decoder.discontinuity = image_discontinuity; - this->video_decoder.dispose = image_dispose; - this->cls = cls; - this->stream = stream; - - /* - * initialisation of privates - */ - - return &this->video_decoder; -} - -/* - * image plugin class - */ -static void *init_class (xine_t *xine, void *data) { - - image_class_t *this; - - this = (image_class_t *) xine_xmalloc (sizeof (image_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "gdkpixbuf"; - this->decoder_class.description = N_("gdk-pixbuf image video decoder plugin"); - this->decoder_class.dispose = default_video_decoder_class_dispose; - - /* - * initialisation of privates - */ - - lprintf("class opened\n"); - - return this; -} - -/* - * exported plugin catalog entry - */ - -static uint32_t supported_types[] = { BUF_VIDEO_IMAGE, BUF_VIDEO_JPEG, 0 }; - -static const decoder_info_t dec_info_image = { - supported_types, /* supported types */ - 7 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_VIDEO_DECODER, 19, "gdkpixbuf", XINE_VERSION_CODE, &dec_info_image, init_class }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libxinevdec/image.c b/src/libxinevdec/image.c deleted file mode 100644 index e84312624..000000000 --- a/src/libxinevdec/image.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (C) 2003-2005 the xine project - * - * This file is part of xine, a free video player. - * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * a image video decoder - */ - - -#include -#include -#include -#include -#include -#include -#include - -#define LOG_MODULE "image_video_decoder" -#define LOG_VERBOSE -/* -#define LOG -*/ - -#include -#ifdef PACKAGE_NAME -#undef PACKAGE_BUGREPORT -#undef PACKAGE_NAME -#undef PACKAGE_STRING -#undef PACKAGE_TARNAME -#undef PACKAGE_VERSION -#endif - -#include -#include -#include -#include -#include "bswap.h" - -typedef struct { - video_decoder_class_t decoder_class; - - /* - * private variables - */ - -} image_class_t; - - -typedef struct image_decoder_s { - video_decoder_t video_decoder; - - image_class_t *cls; - - xine_stream_t *stream; - int video_open; - - unsigned char *image; - int index; - -} image_decoder_t; - - -static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { - image_decoder_t *this = (image_decoder_t *) this_gen; - - if (!this->video_open) { - lprintf("opening video\n"); - (this->stream->video_out->open) (this->stream->video_out, this->stream); - this->video_open = 1; - } - - xine_buffer_copyin(this->image, this->index, buf->mem, buf->size); - this->index += buf->size; - - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { - int width, height, i; - MagickBooleanType status; - MagickWand *wand; - uint8_t *img_buf, *img_buf_ptr; - yuv_planes_t yuv_planes; - vo_frame_t *img; - - /* - * this->image -> rgb data - */ - wand = NewMagickWand(); - status = MagickReadImageBlob(wand, this->image, this->index); - this->index = 0; - - if (status == MagickFalse) { - DestroyMagickWand(wand); - lprintf("error loading image\n"); - return; - } - - width = MagickGetImageWidth(wand) & ~1; /* must be even for init_yuv_planes */ - height = MagickGetImageHeight(wand); - img_buf = malloc(width * height * 3); - MagickGetImagePixels(wand, 0, 0, width, height, "RGB", CharPixel, img_buf); - DestroyMagickWand(wand); - - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, width); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, height); - - lprintf("image loaded successfully\n"); - - /* - * rgb data -> yuv_planes - */ - init_yuv_planes(&yuv_planes, width, height); - - img_buf_ptr = img_buf; - for (i=0; i < width*height; i++) { - uint8_t r = *(img_buf_ptr++); - uint8_t g = *(img_buf_ptr++); - uint8_t b = *(img_buf_ptr++); - - yuv_planes.y[i] = COMPUTE_Y(r, g, b); - yuv_planes.u[i] = COMPUTE_U(r, g, b); - yuv_planes.v[i] = COMPUTE_V(r, g, b); - } - free(img_buf); - - /* - * alloc and draw video frame - */ - img = this->stream->video_out->get_frame (this->stream->video_out, width, - height, (double)width/(double)height, - XINE_IMGFMT_YUY2, - VO_BOTH_FIELDS); - img->pts = buf->pts; - img->duration = 3600; - img->bad_frame = 0; - - yuv444_to_yuy2(&yuv_planes, img->base[0], img->pitches[0]); - free_yuv_planes(&yuv_planes); - - _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, img->duration); - - img->draw(img, this->stream); - img->free(img); - } -} - - -static void image_flush (video_decoder_t *this_gen) { - /* image_decoder_t *this = (image_decoder_t *) this_gen; */ - - /* - * flush out any frames that are still stored in the decoder - */ -} - - -static void image_reset (video_decoder_t *this_gen) { - image_decoder_t *this = (image_decoder_t *) this_gen; - - /* - * reset decoder after engine flush (prepare for new - * video data not related to recently decoded data) - */ - - this->index = 0; -} - - -static void image_discontinuity (video_decoder_t *this_gen) { - /* image_decoder_t *this = (image_decoder_t *) this_gen; */ - - /* - * a time reference discontinuity has happened. - * that is, it must forget any currently held pts value - */ -} - -static void image_dispose (video_decoder_t *this_gen) { - image_decoder_t *this = (image_decoder_t *) this_gen; - - if (this->video_open) { - lprintf("closing video\n"); - - this->stream->video_out->close(this->stream->video_out, this->stream); - this->video_open = 0; - } - - xine_buffer_free(this->image); - - lprintf("closed\n"); - free (this); -} - - -static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, - xine_stream_t *stream) { - - image_class_t *cls = (image_class_t *) class_gen; - image_decoder_t *this; - - lprintf("opened\n"); - - this = (image_decoder_t *) xine_xmalloc (sizeof (image_decoder_t)); - - this->video_decoder.decode_data = image_decode_data; - this->video_decoder.flush = image_flush; - this->video_decoder.reset = image_reset; - this->video_decoder.discontinuity = image_discontinuity; - this->video_decoder.dispose = image_dispose; - this->cls = cls; - this->stream = stream; - - /* - * initialisation of privates - */ - - this->image = xine_buffer_init(10240); - - return &this->video_decoder; -} - -/* - * image plugin class - */ -static void *init_class (xine_t *xine, void *data) { - - image_class_t *this; - - this = (image_class_t *) xine_xmalloc (sizeof (image_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "imagevdec"; - this->decoder_class.description = N_("image video decoder plugin"); - this->decoder_class.dispose = default_video_decoder_class_dispose; - - /* - * initialisation of privates - */ - - lprintf("class opened\n"); - - return this; -} - -/* - * exported plugin catalog entry - */ - -static uint32_t supported_types[] = { BUF_VIDEO_IMAGE, - 0 }; - -static const decoder_info_t dec_info_image = { - supported_types, /* supported types */ - 6 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_VIDEO_DECODER, 19, "image", XINE_VERSION_CODE, &dec_info_image, init_class }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libxinevdec/rgb.c b/src/libxinevdec/rgb.c deleted file mode 100644 index 9c8409e5f..000000000 --- a/src/libxinevdec/rgb.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Copyright (C) 2000-2003 the xine project - * - * This file is part of xine, a free video player. - * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * Raw RGB "Decoder" by Mike Melanson (melanson@pcisys.net) - * Actually, this decoder just converts a raw RGB image to a YUY2 map - * suitable for display under xine. - * - * This decoder deals with raw RGB data from Microsoft and Quicktime files. - * Data from a MS file can be 32-, 24-, 16-, or 8-bit. The latter can also - * be grayscale, depending on whether a palette is present. Data from a QT - * file can be 32-, 24-, 16-, 8-, 4-, 2-, or 1-bit. Any resolutions <= 8 - * can also be greyscale depending on what the QT file specifies. - * - * One more catch: Raw RGB from a Microsoft file is upside down. This is - * indicated by a negative height parameter. - */ - -#include -#include -#include -#include -#include - -#define LOG_MODULE "rgb" -#define LOG_VERBOSE -/* -#define LOG -*/ -#include -#include -#include -#include -#include "bswap.h" - -typedef struct { - video_decoder_class_t decoder_class; -} rgb_class_t; - -typedef struct rgb_decoder_s { - video_decoder_t video_decoder; /* parent video decoder structure */ - - rgb_class_t *class; - xine_stream_t *stream; - - /* these are traditional variables in a video decoder object */ - uint64_t video_step; /* frame duration in pts units */ - int decoder_ok; /* current decoder status */ - int skipframes; - - unsigned char *buf; /* the accumulated buffer data */ - int bufsize; /* the maximum size of buf */ - int size; /* the current size of buf */ - - int width; /* the width of a video frame */ - int height; /* the height of a video frame */ - double ratio; /* the width to height ratio */ - int bytes_per_pixel; - int bit_depth; - int upside_down; - - unsigned char yuv_palette[256 * 4]; - yuv_planes_t yuv_planes; - -} rgb_decoder_t; - -static void rgb_decode_data (video_decoder_t *this_gen, - buf_element_t *buf) { - - rgb_decoder_t *this = (rgb_decoder_t *) this_gen; - xine_bmiheader *bih; - palette_entry_t *palette; - int i; - int pixel_ptr, row_ptr; - int palette_index; - int buf_ptr; - unsigned int packed_pixel; - unsigned char r, g, b; - int pixels_left; - unsigned char pixel_byte = 0; - - vo_frame_t *img; /* video out frame */ - - /* a video decoder does not care about this flag (?) */ - if (buf->decoder_flags & BUF_FLAG_PREVIEW) - return; - - if ((buf->decoder_flags & BUF_FLAG_SPECIAL) && - (buf->decoder_info[1] == BUF_SPECIAL_PALETTE)) { - palette = (palette_entry_t *)buf->decoder_info_ptr[2]; - for (i = 0; i < buf->decoder_info[2]; i++) { - this->yuv_palette[i * 4 + 0] = - COMPUTE_Y(palette[i].r, palette[i].g, palette[i].b); - this->yuv_palette[i * 4 + 1] = - COMPUTE_U(palette[i].r, palette[i].g, palette[i].b); - this->yuv_palette[i * 4 + 2] = - COMPUTE_V(palette[i].r, palette[i].g, palette[i].b); - } - } - - if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { - this->video_step = buf->decoder_info[0]; - _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step); - } - - if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ - (this->stream->video_out->open) (this->stream->video_out, this->stream); - - bih = (xine_bmiheader *) buf->content; - this->width = (bih->biWidth + 3) & ~0x03; - this->height = (bih->biHeight + 3) & ~0x03; - if (this->height < 0) { - this->upside_down = 1; - this->height = -this->height; - } else { - this->upside_down = 0; - } - this->ratio = (double)this->width/(double)this->height; - - this->bit_depth = bih->biBitCount; - if (this->bit_depth > 32) - this->bit_depth &= 0x1F; - /* round this number up in case of 15 */ - lprintf("width = %d, height = %d, bit_depth = %d\n", this->width, this->height, this->bit_depth); - - this->bytes_per_pixel = (this->bit_depth + 1) / 8; - - free (this->buf); - - /* minimal buffer size */ - this->bufsize = this->width * this->height * this->bytes_per_pixel; - this->buf = xine_xmalloc(this->bufsize); - this->size = 0; - - init_yuv_planes(&this->yuv_planes, this->width, this->height); - - (this->stream->video_out->open) (this->stream->video_out, this->stream); - this->decoder_ok = 1; - - /* load the stream/meta info */ - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw RGB"); - - return; - } else if (this->decoder_ok) { - - if (this->size + buf->size > this->bufsize) { - this->bufsize = this->size + 2 * buf->size; - this->buf = realloc (this->buf, this->bufsize); - } - xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); - - this->size += buf->size; - - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { - - img = this->stream->video_out->get_frame (this->stream->video_out, - this->width, this->height, - this->ratio, XINE_IMGFMT_YUY2, - VO_BOTH_FIELDS); - - img->duration = this->video_step; - img->pts = buf->pts; - img->bad_frame = 0; - - - /* iterate through each row */ - buf_ptr = 0; - - if (this->upside_down) { - for (row_ptr = this->yuv_planes.row_width * (this->yuv_planes.row_count - 1); - row_ptr >= 0; row_ptr -= this->yuv_planes.row_width) { - for (pixel_ptr = 0; pixel_ptr < this->width; pixel_ptr++) { - - if (this->bytes_per_pixel == 1) { - - palette_index = this->buf[buf_ptr++]; - - this->yuv_planes.y[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 0]; - this->yuv_planes.u[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 1]; - this->yuv_planes.v[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 2]; - - } else if (this->bytes_per_pixel == 2) { - - /* ABGR1555 format, little-endian order */ - packed_pixel = _X_LE_16(&this->buf[buf_ptr]); - buf_ptr += 2; - UNPACK_BGR15(packed_pixel, r, g, b); - - this->yuv_planes.y[row_ptr + pixel_ptr] = - COMPUTE_Y(r, g, b); - this->yuv_planes.u[row_ptr + pixel_ptr] = - COMPUTE_U(r, g, b); - this->yuv_planes.v[row_ptr + pixel_ptr] = - COMPUTE_V(r, g, b); - - } else { - - /* BGR24 or BGRA32 */ - b = this->buf[buf_ptr++]; - g = this->buf[buf_ptr++]; - r = this->buf[buf_ptr++]; - - /* the next line takes care of 'A' in the 32-bit case */ - buf_ptr += this->bytes_per_pixel - 3; - - this->yuv_planes.y[row_ptr + pixel_ptr] = - COMPUTE_Y(r, g, b); - this->yuv_planes.u[row_ptr + pixel_ptr] = - COMPUTE_U(r, g, b); - this->yuv_planes.v[row_ptr + pixel_ptr] = - COMPUTE_V(r, g, b); - - } - } - } - } else { - - for (row_ptr = 0; row_ptr < this->yuv_planes.row_width * this->yuv_planes.row_count; row_ptr += this->yuv_planes.row_width) { - pixels_left = 0; - for (pixel_ptr = 0; pixel_ptr < this->width; pixel_ptr++) { - - if (this->bit_depth == 1) { - - if (pixels_left == 0) { - pixels_left = 8; - pixel_byte = *this->buf++; - } - - if (pixel_byte & 0x80) { - this->yuv_planes.y[row_ptr + pixel_ptr] = - this->yuv_palette[1 * 4 + 0]; - this->yuv_planes.u[row_ptr + pixel_ptr] = - this->yuv_palette[1 * 4 + 1]; - this->yuv_planes.v[row_ptr + pixel_ptr] = - this->yuv_palette[1 * 4 + 2]; - } else { - this->yuv_planes.y[row_ptr + pixel_ptr] = - this->yuv_palette[0 * 4 + 0]; - this->yuv_planes.u[row_ptr + pixel_ptr] = - this->yuv_palette[0 * 4 + 1]; - this->yuv_planes.v[row_ptr + pixel_ptr] = - this->yuv_palette[0 * 4 + 2]; - } - pixels_left--; - pixel_byte <<= 1; - - } else if (this->bit_depth == 2) { - - if (pixels_left == 0) { - pixels_left = 4; - pixel_byte = *this->buf++; - } - - palette_index = (pixel_byte & 0xC0) >> 6; - this->yuv_planes.y[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 0]; - this->yuv_planes.u[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 1]; - this->yuv_planes.v[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 2]; - - pixels_left--; - pixel_byte <<= 2; - - } else if (this->bit_depth == 4) { - - if (pixels_left == 0) { - pixels_left = 2; - pixel_byte = *this->buf++; - } - - palette_index = (pixel_byte & 0xF0) >> 4; - this->yuv_planes.y[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 0]; - this->yuv_planes.u[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 1]; - this->yuv_planes.v[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 2]; - - pixels_left--; - pixel_byte <<= 4; - - } else if (this->bytes_per_pixel == 1) { - - palette_index = this->buf[buf_ptr++]; - - this->yuv_planes.y[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 0]; - this->yuv_planes.u[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 1]; - this->yuv_planes.v[row_ptr + pixel_ptr] = - this->yuv_palette[palette_index * 4 + 2]; - - } else if (this->bytes_per_pixel == 2) { - - /* ARGB1555 format, big-endian order */ - packed_pixel = _X_BE_16(&this->buf[buf_ptr]); - buf_ptr += 2; - UNPACK_RGB15(packed_pixel, r, g, b); - - this->yuv_planes.y[row_ptr + pixel_ptr] = - COMPUTE_Y(r, g, b); - this->yuv_planes.u[row_ptr + pixel_ptr] = - COMPUTE_U(r, g, b); - this->yuv_planes.v[row_ptr + pixel_ptr] = - COMPUTE_V(r, g, b); - - } else { - - /* RGB24 or ARGB32; the next line takes care of 'A' in the - * 32-bit case */ - buf_ptr += this->bytes_per_pixel - 3; - - r = this->buf[buf_ptr++]; - g = this->buf[buf_ptr++]; - b = this->buf[buf_ptr++]; - - this->yuv_planes.y[row_ptr + pixel_ptr] = - COMPUTE_Y(r, g, b); - this->yuv_planes.u[row_ptr + pixel_ptr] = - COMPUTE_U(r, g, b); - this->yuv_planes.v[row_ptr + pixel_ptr] = - COMPUTE_V(r, g, b); - - } - } - } - } - - yuv444_to_yuy2(&this->yuv_planes, img->base[0], img->pitches[0]); - - img->draw(img, this->stream); - img->free(img); - - this->size = 0; - } - } -} - -/* - * This function is called when xine needs to flush the system. Not - * sure when or if this is used or even if it needs to do anything. - */ -static void rgb_flush (video_decoder_t *this_gen) { -} - -/* - * This function resets the video decoder. - */ -static void rgb_reset (video_decoder_t *this_gen) { - rgb_decoder_t *this = (rgb_decoder_t *) this_gen; - - this->size = 0; -} - -static void rgb_discontinuity (video_decoder_t *this_gen) { -} - -/* - * This function frees the video decoder instance allocated to the decoder. - */ -static void rgb_dispose (video_decoder_t *this_gen) { - rgb_decoder_t *this = (rgb_decoder_t *) this_gen; - - free (this->buf); - - if (this->decoder_ok) { - this->decoder_ok = 0; - this->stream->video_out->close(this->stream->video_out, this->stream); - } - - free (this_gen); -} - -static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { - - rgb_decoder_t *this ; - - this = (rgb_decoder_t *) xine_xmalloc (sizeof (rgb_decoder_t)); - - this->video_decoder.decode_data = rgb_decode_data; - this->video_decoder.flush = rgb_flush; - this->video_decoder.reset = rgb_reset; - this->video_decoder.discontinuity = rgb_discontinuity; - this->video_decoder.dispose = rgb_dispose; - this->size = 0; - - this->stream = stream; - this->class = (rgb_class_t *) class_gen; - - this->decoder_ok = 0; - this->buf = NULL; - - return &this->video_decoder; -} - -static void *init_plugin (xine_t *xine, void *data) { - - rgb_class_t *this; - - this = (rgb_class_t *) xine_xmalloc (sizeof (rgb_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "RGB"; - this->decoder_class.description = N_("Raw RGB video decoder plugin"); - this->decoder_class.dispose = default_video_decoder_class_dispose; - - return this; -} - -/* - * exported plugin catalog entry - */ - -static const uint32_t video_types[] = { - BUF_VIDEO_RGB, - 0 - }; - -static const decoder_info_t dec_info_video = { - video_types, /* supported types */ - 1 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_VIDEO_DECODER, 19, "rgb", XINE_VERSION_CODE, &dec_info_video, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libxinevdec/yuv.c b/src/libxinevdec/yuv.c deleted file mode 100644 index c1e5825c5..000000000 --- a/src/libxinevdec/yuv.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Copyright (C) 2000-2004 the xine project - * - * This file is part of xine, a free video player. - * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * YUV "Decoder" by Mike Melanson (melanson@pcisys.net) - * Actually, this decoder just reorganizes chunks of raw YUV data in such - * a way that xine can display them. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "bswap.h" - -#define VIDEOBUFSIZE 128*1024 - -typedef struct { - video_decoder_class_t decoder_class; -} yuv_class_t; - -typedef struct yuv_decoder_s { - video_decoder_t video_decoder; /* parent video decoder structure */ - - yuv_class_t *class; - xine_stream_t *stream; - - /* these are traditional variables in a video decoder object */ - uint64_t video_step; /* frame duration in pts units */ - int decoder_ok; /* current decoder status */ - int skipframes; - - unsigned char *buf; /* the accumulated buffer data */ - int bufsize; /* the maximum size of buf */ - int size; /* the current size of buf */ - - int width; /* the width of a video frame */ - int height; /* the height of a video frame */ - double ratio; /* the width to height ratio */ - - int progressive; - int top_field_first; - -} yuv_decoder_t; - -/************************************************************************** - * xine video plugin functions - *************************************************************************/ - -/* - * This function receives a buffer of data from the demuxer layer and - * figures out how to handle it based on its header flags. - */ -static void yuv_decode_data (video_decoder_t *this_gen, - buf_element_t *buf) { - - yuv_decoder_t *this = (yuv_decoder_t *) this_gen; - xine_bmiheader *bih; - - vo_frame_t *img; /* video out frame */ - - /* a video decoder does not care about this flag (?) */ - if (buf->decoder_flags & BUF_FLAG_PREVIEW) - return; - - if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { - this->video_step = buf->decoder_info[0]; - _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step); - } - - if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ - (this->stream->video_out->open) (this->stream->video_out, this->stream); - - bih = (xine_bmiheader *) buf->content; - this->width = (bih->biWidth + 3) & ~0x03; - this->height = (bih->biHeight + 3) & ~0x03; - - if (buf->decoder_flags & BUF_FLAG_ASPECT) - this->ratio = (double)buf->decoder_info[1] / (double)buf->decoder_info[2]; - else - this->ratio = (double)this->width / (double)this->height; - - this->progressive = buf->decoder_info[3]; - this->top_field_first = buf->decoder_info[4]; - - free (this->buf); - this->buf = NULL; - - this->bufsize = VIDEOBUFSIZE; - this->buf = malloc(this->bufsize); - this->size = 0; - - this->decoder_ok = 1; - - /* load the stream/meta info */ - switch (buf->type) { - - case BUF_VIDEO_YUY2: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw YUY2"); - break; - - case BUF_VIDEO_YV12: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw YV12"); - break; - - case BUF_VIDEO_YVU9: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw YVU9"); - break; - - case BUF_VIDEO_GREY: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Greyscale YUV"); - break; - - case BUF_VIDEO_I420: - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw I420"); - break; - - } - - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->width); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->height); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, this->ratio*10000); - - return; - } else if (this->decoder_ok && !(buf->decoder_flags & BUF_FLAG_SPECIAL)) { - uint8_t *src; - - /* if buffer contains an entire frame then there's no need to copy it - * into our internal buffer */ - if ((buf->decoder_flags & BUF_FLAG_FRAME_START) && - (buf->decoder_flags & BUF_FLAG_FRAME_END)) - src = buf->content; - else { - if (this->size + buf->size > this->bufsize) { - this->bufsize = this->size + 2 * buf->size; - this->buf = realloc (this->buf, this->bufsize); - } - - xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); - - this->size += buf->size; - - src = this->buf; - } - - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { - - if (buf->type == BUF_VIDEO_YUY2) { - - img = this->stream->video_out->get_frame (this->stream->video_out, - this->width, this->height, - this->ratio, XINE_IMGFMT_YUY2, VO_BOTH_FIELDS); - - yuy2_to_yuy2( - /* src */ - src, this->width*2, - /* dst */ - img->base[0], img->pitches[0], - /* width x height */ - this->width, this->height); - - } else if (buf->type == BUF_VIDEO_YV12) { - - img = this->stream->video_out->get_frame (this->stream->video_out, - this->width, this->height, - this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); - - yv12_to_yv12( - /* Y */ - src, this->width, - img->base[0], img->pitches[0], - /* U */ - src + (this->width * this->height * 5/4), this->width/2, - img->base[1], img->pitches[1], - /* V */ - src + (this->width * this->height), this->width/2, - img->base[2], img->pitches[2], - /* width x height */ - this->width, this->height); - - } else if (buf->type == BUF_VIDEO_I420) { - - img = this->stream->video_out->get_frame (this->stream->video_out, - this->width, this->height, - this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); - - yv12_to_yv12( - /* Y */ - src, this->width, - img->base[0], img->pitches[0], - /* U */ - src + (this->width * this->height), this->width/2, - img->base[1], img->pitches[1], - /* V */ - src + (this->width * this->height * 5/4), this->width/2, - img->base[2], img->pitches[2], - /* width x height */ - this->width, this->height); - - } else if (buf->type == BUF_VIDEO_YVU9) { - - img = this->stream->video_out->get_frame (this->stream->video_out, - this->width, this->height, - this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); - - - yuv9_to_yv12( - /* Y */ - src, - this->width, - img->base[0], - img->pitches[0], - /* U */ - src + (this->width * this->height), - this->width / 4, - img->base[1], - img->pitches[1], - /* V */ - src + (this->width * this->height) + - (this->width * this->height / 16), - this->width / 4, - img->base[2], - img->pitches[2], - /* width x height */ - this->width, - this->height); - - } else if (buf->type == BUF_VIDEO_GREY) { - - img = this->stream->video_out->get_frame (this->stream->video_out, - this->width, this->height, - this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); - - xine_fast_memcpy(img->base[0], src, this->width * this->height); - memset( img->base[1], 0x80, this->width * this->height / 4 ); - memset( img->base[2], 0x80, this->width * this->height / 4 ); - - } else { - - /* just allocate something to avoid compiler warnings */ - img = this->stream->video_out->get_frame (this->stream->video_out, - this->width, this->height, - this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); - - } - - img->duration = this->video_step; - img->pts = buf->pts; - img->bad_frame = 0; - - img->draw(img, this->stream); - img->free(img); - - this->size = 0; - } - } -} - -/* - * This function is called when xine needs to flush the system. Not - * sure when or if this is used or even if it needs to do anything. - */ -static void yuv_flush (video_decoder_t *this_gen) { -} - -/* - * This function resets the video decoder. - */ -static void yuv_reset (video_decoder_t *this_gen) { - yuv_decoder_t *this = (yuv_decoder_t *) this_gen; - - this->size = 0; -} - -static void yuv_discontinuity (video_decoder_t *this_gen) { -} - -/* - * This function frees the video decoder instance allocated to the decoder. - */ -static void yuv_dispose (video_decoder_t *this_gen) { - yuv_decoder_t *this = (yuv_decoder_t *) this_gen; - - free (this->buf); - - if (this->decoder_ok) { - this->decoder_ok = 0; - this->stream->video_out->close(this->stream->video_out, this->stream); - } - - free (this_gen); -} - -static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { - - yuv_decoder_t *this ; - - this = (yuv_decoder_t *) xine_xmalloc (sizeof (yuv_decoder_t)); - - this->video_decoder.decode_data = yuv_decode_data; - this->video_decoder.flush = yuv_flush; - this->video_decoder.reset = yuv_reset; - this->video_decoder.discontinuity = yuv_discontinuity; - this->video_decoder.dispose = yuv_dispose; - this->size = 0; - - this->stream = stream; - this->class = (yuv_class_t *) class_gen; - - this->decoder_ok = 0; - this->buf = NULL; - - return &this->video_decoder; -} - -static void *init_plugin (xine_t *xine, void *data) { - - yuv_class_t *this; - - this = (yuv_class_t *) xine_xmalloc (sizeof (yuv_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.identifier = "YUV"; - this->decoder_class.description = N_("Raw YUV video decoder plugin"); - this->decoder_class.dispose = default_video_decoder_class_dispose; - - return this; -} - -/* - * exported plugin catalog entry - */ - -static const uint32_t video_types[] = { - BUF_VIDEO_YUY2, - BUF_VIDEO_YV12, - BUF_VIDEO_YVU9, - BUF_VIDEO_GREY, - BUF_VIDEO_I420, - 0 - }; - -static const decoder_info_t dec_info_video = { - video_types, /* supported types */ - 1 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_VIDEO_DECODER, 19, "yuv", XINE_VERSION_CODE, &dec_info_video, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/video_dec/Makefile.am b/src/video_dec/Makefile.am new file mode 100644 index 000000000..321d70c1f --- /dev/null +++ b/src/video_dec/Makefile.am @@ -0,0 +1,38 @@ +include $(top_srcdir)/misc/Makefile.common + +AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) +AM_LDFLAGS = $(xineplug_ldflags) + +EXTRA_DIST = foovideo.c + +if ENABLE_IMAGEMAGICK +image_module = xineplug_decode_image.la +endif + +if ENABLE_GDK_PIXBUF +gdkpixbuf_module = xineplug_decode_gdk_pixbuf.la +endif + +xineplug_LTLIBRARIES = $(image_module) \ + $(gdkpixbuf_module) \ + $(theora_module) \ + xineplug_decode_bitplane.la \ + xineplug_decode_rgb.la \ + xineplug_decode_yuv.la + +xineplug_decode_bitplane_la_SOURCES = bitplane.c +xineplug_decode_bitplane_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) + +xineplug_decode_rgb_la_SOURCES = rgb.c +xineplug_decode_rgb_la_LIBADD = $(XINE_LIB) + +xineplug_decode_yuv_la_SOURCES = yuv.c +xineplug_decode_yuv_la_LIBADD = $(XINE_LIB) + +xineplug_decode_image_la_SOURCES = image.c +xineplug_decode_image_la_LIBADD = $(XINE_LIB) $(DYNAMIC_LD_LIBS) $(WAND_LIBS) +xineplug_decode_image_la_CFLAGS = $(AM_CFLAGS) $(WAND_CFLAGS) + +xineplug_decode_gdk_pixbuf_la_SOURCES = gdkpixbuf.c +xineplug_decode_gdk_pixbuf_la_LIBADD = $(XINE_LIB) $(DYNAMIC_LD_LIBS) $(GDK_PIXBUF_LIBS) +xineplug_decode_gdk_pixbuf_la_CFLAGS = $(AM_CFLAGS) $(GDK_PIXBUF_CFLAGS) diff --git a/src/video_dec/bitplane.c b/src/video_dec/bitplane.c new file mode 100644 index 000000000..327e14aee --- /dev/null +++ b/src/video_dec/bitplane.c @@ -0,0 +1,1554 @@ +/* + * Copyright (C) 2004 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Bitplane "Decoder" by Manfred Tremmel (Manfred.Tremmel@iiv.de) + * Converts Amiga typical bitplane pictures to a YUV2 map + * suitable for display under xine. It's based on the rgb-decoder + * and the development documentation from the Amiga Developer CD + * + * Supported formats: + * - uncompressed and byterun1 compressed ILBM data + * - IFF ANIM compression methods OPT 5, 7 (long and short) and + * 8 (long and short) + * - untested (found no testfiles) IFF-ANIM OPT 3, 4 and 6 + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "bswap.h" + +#include "demuxers/iff.h" + +#define IFF_REPLACE_BYTE_SIMPLE(ptr, old_data, new_data, colorindexx ) { \ + register uint8_t *index_ptr = ptr; \ + register uint8_t colorindex = colorindexx; \ + *index_ptr -= ((old_data & 0x80) ? colorindex : 0); \ + *index_ptr++ += ((new_data & 0x80) ? colorindex : 0); \ + *index_ptr -= ((old_data & 0x40) ? colorindex : 0); \ + *index_ptr++ += ((new_data & 0x40) ? colorindex : 0); \ + *index_ptr -= ((old_data & 0x20) ? colorindex : 0); \ + *index_ptr++ += ((new_data & 0x20) ? colorindex : 0); \ + *index_ptr -= ((old_data & 0x10) ? colorindex : 0); \ + *index_ptr++ += ((new_data & 0x10) ? colorindex : 0); \ + *index_ptr -= ((old_data & 0x08) ? colorindex : 0); \ + *index_ptr++ += ((new_data & 0x08) ? colorindex : 0); \ + *index_ptr -= ((old_data & 0x04) ? colorindex : 0); \ + *index_ptr++ += ((new_data & 0x04) ? colorindex : 0); \ + *index_ptr -= ((old_data & 0x02) ? colorindex : 0); \ + *index_ptr++ += ((new_data & 0x02) ? colorindex : 0); \ + *index_ptr -= ((old_data & 0x01) ? colorindex : 0); \ + *index_ptr += ((new_data & 0x01) ? colorindex : 0); \ + old_data = new_data; \ +} + +#define IFF_REPLACE_BYTE(ptr, yuvy, yuvu, yuvv, yuv_palette, old_data, new_data, colorindexx ) { \ + register uint8_t *index_ptr = ptr; \ + register uint8_t colorindex = colorindexx; \ + register uint8_t *yuv_y = yuvy; \ + register uint8_t *yuv_u = yuvu; \ + register uint8_t *yuv_v = yuvv; \ + *index_ptr -= ((old_data & 0x80) ? colorindex : 0); \ + *index_ptr += ((new_data & 0x80) ? colorindex : 0); \ + yuv_index = *index_ptr++ * 4; \ + *yuv_y++ = yuv_palette[yuv_index++]; \ + *yuv_u++ = yuv_palette[yuv_index++]; \ + *yuv_v++ = yuv_palette[yuv_index]; \ + *index_ptr -= ((old_data & 0x40) ? colorindex : 0); \ + *index_ptr += ((new_data & 0x40) ? colorindex : 0); \ + yuv_index = *index_ptr++ * 4; \ + *yuv_y++ = yuv_palette[yuv_index++]; \ + *yuv_u++ = yuv_palette[yuv_index++]; \ + *yuv_v++ = yuv_palette[yuv_index]; \ + *index_ptr -= ((old_data & 0x20) ? colorindex : 0); \ + *index_ptr += ((new_data & 0x20) ? colorindex : 0); \ + yuv_index = *index_ptr++ * 4; \ + *yuv_y++ = yuv_palette[yuv_index++]; \ + *yuv_u++ = yuv_palette[yuv_index++]; \ + *yuv_v++ = yuv_palette[yuv_index]; \ + *index_ptr -= ((old_data & 0x10) ? colorindex : 0); \ + *index_ptr += ((new_data & 0x10) ? colorindex : 0); \ + yuv_index = *index_ptr++ * 4; \ + *yuv_y++ = yuv_palette[yuv_index++]; \ + *yuv_u++ = yuv_palette[yuv_index++]; \ + *yuv_v++ = yuv_palette[yuv_index]; \ + *index_ptr -= ((old_data & 0x08) ? colorindex : 0); \ + *index_ptr += ((new_data & 0x08) ? colorindex : 0); \ + yuv_index = *index_ptr++ * 4; \ + *yuv_y++ = yuv_palette[yuv_index++]; \ + *yuv_u++ = yuv_palette[yuv_index++]; \ + *yuv_v++ = yuv_palette[yuv_index]; \ + *index_ptr -= ((old_data & 0x04) ? colorindex : 0); \ + *index_ptr += ((new_data & 0x04) ? colorindex : 0); \ + yuv_index = *index_ptr++ * 4; \ + *yuv_y++ = yuv_palette[yuv_index++]; \ + *yuv_u++ = yuv_palette[yuv_index++]; \ + *yuv_v++ = yuv_palette[yuv_index]; \ + *index_ptr -= ((old_data & 0x02) ? colorindex : 0); \ + *index_ptr += ((new_data & 0x02) ? colorindex : 0); \ + yuv_index = *index_ptr++ * 4; \ + *yuv_y++ = yuv_palette[yuv_index++]; \ + *yuv_u++ = yuv_palette[yuv_index++]; \ + *yuv_v++ = yuv_palette[yuv_index]; \ + *index_ptr -= ((old_data & 0x01) ? colorindex : 0); \ + *index_ptr += ((new_data & 0x01) ? colorindex : 0); \ + yuv_index = *index_ptr * 4; \ + *yuv_y = yuv_palette[yuv_index++]; \ + *yuv_u = yuv_palette[yuv_index++]; \ + *yuv_v = yuv_palette[yuv_index]; \ + old_data = new_data; \ +} + +#define IFF_REPLACE_SHORT_SIMPLE(ptr_s, old_data_s, new_data_s, colorindexx_s ) { \ + uint8_t *xindex_ptr = (uint8_t *)ptr_s; \ + uint8_t *xold_data = (uint8_t *)old_data_s; \ + uint8_t *xnew_data = (uint8_t *)new_data_s; \ + IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_s ); \ + xindex_ptr += 8; \ + xold_data++; \ + xnew_data++; \ + IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_s ); \ +} + +#define IFF_REPLACE_SHORT(ptr_s, yuvy_s, yuvu_s, yuvv_s, yuv_palette_s, old_data_s, new_data_s, colorindexx_s ) { \ + uint8_t *xindex_ptr = (uint8_t *)ptr_s; \ + uint8_t *xold_data = (uint8_t *)old_data_s; \ + uint8_t *xnew_data = (uint8_t *)new_data_s; \ + uint8_t *xyuv_y = yuvy_s; \ + uint8_t *xyuv_u = yuvu_s; \ + uint8_t *xyuv_v = yuvv_s; \ + IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_s, *xold_data, *xnew_data, colorindexx_s ); \ + xindex_ptr += 8; \ + xold_data++; \ + xnew_data++; \ + xyuv_y += 8; \ + xyuv_u += 8; \ + xyuv_v += 8; \ + IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_s, *xold_data, *xnew_data, colorindexx_s ); \ +} + +#define IFF_REPLACE_LONG_SIMPLE(ptr_l, old_data_l, new_data_l, colorindexx_l ) { \ + uint8_t *xindex_ptr = (uint8_t *)ptr_l; \ + uint8_t *xold_data = (uint8_t *)old_data_l; \ + uint8_t *xnew_data = (uint8_t *)new_data_l; \ + IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_l ); \ + xindex_ptr += 8; \ + xold_data++; \ + xnew_data++; \ + IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_l ); \ + xindex_ptr += 8; \ + xold_data++; \ + xnew_data++; \ + IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_l ); \ + xindex_ptr += 8; \ + xold_data++; \ + xnew_data++; \ + IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_l ); \ +} + +#define IFF_REPLACE_LONG(ptr_l, yuvy_l, yuvu_l, yuvv_l, yuv_palette_l, old_data_l, new_data_l, colorindexx_l ) { \ + uint8_t *xindex_ptr = (uint8_t *)ptr_l; \ + uint8_t *xold_data = (uint8_t *)old_data_l; \ + uint8_t *xnew_data = (uint8_t *)new_data_l; \ + uint8_t *xyuv_y = yuvy_l; \ + uint8_t *xyuv_u = yuvu_l; \ + uint8_t *xyuv_v = yuvv_l; \ + IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_l, *xold_data, *xnew_data, colorindexx_l ); \ + xindex_ptr += 8; \ + xold_data++; \ + xnew_data++; \ + xyuv_y += 8; \ + xyuv_u += 8; \ + xyuv_v += 8; \ + IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_l, *xold_data, *xnew_data, colorindexx_l ); \ + xindex_ptr += 8; \ + xold_data++; \ + xnew_data++; \ + xyuv_y += 8; \ + xyuv_u += 8; \ + xyuv_v += 8; \ + IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_l, *xold_data, *xnew_data, colorindexx_l ); \ + xindex_ptr += 8; \ + xold_data++; \ + xnew_data++; \ + xyuv_y += 8; \ + xyuv_u += 8; \ + xyuv_v += 8; \ + IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_l, *xold_data, *xnew_data, colorindexx_l ); \ +} + +typedef struct { + video_decoder_class_t decoder_class; +} bitplane_class_t; + +typedef struct bitplane_decoder_s { + video_decoder_t video_decoder; /* parent video decoder structure */ + + bitplane_class_t *class; + xine_stream_t *stream; + + /* these are traditional variables in a video decoder object */ + uint64_t video_step; /* frame duration in pts units */ + int decoder_ok; /* current decoder status */ + int skipframes; /* 0 = draw picture, 1 = skip it */ + int framenumber; + + unsigned char *buf; /* the accumulated buffer data */ + int bufsize; /* the maximum size of buf */ + int size; /* the current size of buf */ + int size_uk; /* size of unkompressed bitplane */ + + int width; /* the width of a video frame */ + int height; /* the height of a video frame */ + int num_pixel; /* number pixel */ + double ratio; /* the width to height ratio */ + int bytes_per_pixel; + int num_bitplanes; + int camg_mode; + int is_ham; + + unsigned char yuv_palette[256 * 4]; + unsigned char rgb_palette[256 * 4]; + yuv_planes_t yuv_planes; + yuv_planes_t yuv_planes_hist; + + uint8_t *buf_uk; /* uncompressed buffer */ + uint8_t *buf_uk_hist; /* uncompressed buffer historic */ + uint8_t *index_buf; /* index buffer (for indexed pics) */ + uint8_t *index_buf_hist;/* index buffer historic */ + +} bitplane_decoder_t; + +/* create a new buffer and decde a byterun1 decoded buffer into it */ +static uint8_t *bitplane_decode_byterun1 (uint8_t *compressed, + int size_compressed, + int size_uncompressed) { + + /* BytRun1 decompression */ + int pixel_ptr = 0; + int i = 0; + int j = 0; + + uint8_t *uncompressed = xine_xmalloc( size_uncompressed ); + + while ( i < size_compressed && + pixel_ptr < size_uncompressed ) { + if( compressed[i] <= 127 ) { + j = compressed[i++]; + if( (i+j) > size_compressed ) { + free(uncompressed); + return NULL; + } + for( ; (j >= 0) && (pixel_ptr < size_uncompressed); j-- ) { + uncompressed[pixel_ptr++] = compressed[i++]; + } + } else if ( compressed[i] > 128 ) { + j = 256 - compressed[i++]; + if( i >= size_compressed ) { + free(uncompressed); + return NULL; + } + for( ; (j >= 0) && (pixel_ptr < size_uncompressed); j-- ) { + uncompressed[pixel_ptr++] = compressed[i]; + } + i++; + } + } + return uncompressed; +} + +/* create a new buffer with "normal" index or rgb numbers out of a bitplane */ +static void bitplane_decode_bitplane (uint8_t *bitplane_buffer, + uint8_t *index_buf, + int width, + int height, + int num_bitplanes, + int bytes_per_pixel ) { + + int rowsize = width / 8; + int pixel_ptr = 0; + int row_ptr = 0; + int palette_index = 0; + int i = 0; + int j = 0; + int row_i = 0; + int row_j = 0; + int palette_offset = 0; + int palette_index_rowsize = 0; + uint8_t color = 0; + uint8_t data = 0; + int bytes_per_pixel_8 = bytes_per_pixel * 8; + int rowsize_num_bitplanes = rowsize * num_bitplanes; + int width_bytes_per_pixel = width * bytes_per_pixel; + + for (i = 0; i < (height * width_bytes_per_pixel); index_buf[i++] = 0); + + /* decode Bitplanes to RGB/Index Numbers */ + for (row_ptr = 0; row_ptr < height; row_ptr++) { + + row_i = row_ptr * width_bytes_per_pixel; + row_j = row_ptr * rowsize_num_bitplanes; + + for (palette_index = 0; palette_index < num_bitplanes; palette_index++) { + + palette_offset = ((palette_index > 15) ? 2 : (palette_index > 7) ? 1 : 0); + color = bitplainoffeset[palette_index]; + palette_index_rowsize = palette_index * rowsize; + + for (pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { + i = row_i + + (pixel_ptr * bytes_per_pixel_8) + + palette_offset; + j = row_j + palette_index_rowsize + pixel_ptr; + + data = bitplane_buffer[j]; + + index_buf[i] += ((data & 0x80) ? color : 0); + i += bytes_per_pixel; + index_buf[i] += ((data & 0x40) ? color : 0); + i += bytes_per_pixel; + index_buf[i] += ((data & 0x20) ? color : 0); + i += bytes_per_pixel; + index_buf[i] += ((data & 0x10) ? color : 0); + i += bytes_per_pixel; + index_buf[i] += ((data & 0x08) ? color : 0); + i += bytes_per_pixel; + index_buf[i] += ((data & 0x04) ? color : 0); + i += bytes_per_pixel; + index_buf[i] += ((data & 0x02) ? color : 0); + i += bytes_per_pixel; + index_buf[i] += ((data & 0x01) ? color : 0); + } + } + } +} + +/* create Buffer decode HAM6 and HAM8 to YUV color */ +static void bitplane_decode_ham (uint8_t *ham_buffer, + yuv_planes_t *yuv_planes, + int width, + int height, + int num_bitplanes, + int bytes_per_pixel, + unsigned char *rgb_palette ) { + + uint8_t *ham_buffer_work = ham_buffer; + uint8_t *ham_buffer_end = &ham_buffer[(width * height)]; + uint8_t *yuv_ptr_y = yuv_planes->y; + uint8_t *yuv_ptr_u = yuv_planes->u; + uint8_t *yuv_ptr_v = yuv_planes->v; + int i = 0; + int j = 0; + uint8_t r = 0; + uint8_t g = 0; + uint8_t b = 0; + /* position of special HAM-Bits differs in HAM6 and HAM8, detect them */ + int hambits = num_bitplanes > 6 ? 6 : 4; + /* the other bits contain the real data, dreate a mask out of it */ + int maskbits = 8 - hambits; + int mask = ( 1 << hambits ) - 1; + + for(; ham_buffer_work < ham_buffer_end; j = *ham_buffer_work++) { + i = (j & mask); + switch ( j >> hambits ) { + case HAMBITS_CMAP: + /* Take colors from palette */ + r = rgb_palette[i * 4 + 0]; + g = rgb_palette[i * 4 + 1]; + b = rgb_palette[i * 4 + 2]; + break; + case HAMBITS_BLUE: + /* keep red and green and modify blue */ + b = i << maskbits; + b |= b >> hambits; + break; + case HAMBITS_RED: + /* keep green and blue and modify red */ + r = i << maskbits; + r |= r >> hambits; + break; + case HAMBITS_GREEN: + /* keep red and blue and modify green */ + g = i << maskbits; + g |= g >> hambits; + break; + default: + break; + } + *yuv_ptr_y++ = COMPUTE_Y(r, g, b); + *yuv_ptr_u++ = COMPUTE_U(r, g, b); + *yuv_ptr_v++ = COMPUTE_V(r, g, b); + } +} + +/* decoding method 3 */ +static void bitplane_sdelta_opt_3 (bitplane_decoder_t *this) { + + uint32_t rowsize = this->width / 16; + uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; + + uint32_t palette_index = 0; + uint32_t *deltadata = (uint32_t *)this->buf; + uint16_t *ptr = NULL; + uint16_t *planeptr = NULL; + uint16_t *picture_end = (uint16_t *)(&this->buf_uk[(rowsize_all_planes * 2 * this->height)]); + uint16_t *data = NULL; + uint16_t *data_end = (uint16_t *)(&this->buf[this->size]); + uint16_t *rowworkptr = NULL; + int16_t s = 0; + int16_t size = 0; + uint32_t pixel_ptr_bit = 0; + uint32_t row_ptr = 0; + uint32_t yuv_index = 0; + + /* Repeat for each plane */ + for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { + + planeptr = (uint16_t *)(&this->buf_uk[(palette_index * rowsize * 2)]); + /* data starts at beginn of delta-Buffer + offset of the first */ + /* 32 Bit long word in the buffer. The buffer starts with 8 */ + /* of this Offset, for every bitplane (max 8) one */ + data = (uint16_t *)(&this->buf[_X_BE_32(&deltadata[palette_index])]); + if( data != (uint16_t *)this->buf ) { + /* This 8 Pointers are followd by another 8 */ + ptr = (uint16_t *)(&this->buf[_X_BE_32(&deltadata[(palette_index+8)])]); + + /* in this case, I think big/little endian is not important ;-) */ + while( *data != 0xFFFF) { + row_ptr = 0; + size = _X_BE_16(data); + data++; + if( size >= 0 ) { + rowworkptr = planeptr + size; + pixel_ptr_bit = size * 16; + if( this->is_ham ) { + IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[pixel_ptr_bit], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_SHORT( &this->index_buf[pixel_ptr_bit], + &this->yuv_planes.y[pixel_ptr_bit], &this->yuv_planes.u[pixel_ptr_bit], + &this->yuv_planes.v[pixel_ptr_bit], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + data++; + } else { + size = 0 - size + 2; + rowworkptr = planeptr + size; + pixel_ptr_bit = size * 16; + s = _X_BE_16(data); + data++; + while( s--) { + if( this->is_ham ) { + IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[pixel_ptr_bit], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_SHORT( &this->index_buf[pixel_ptr_bit], + &this->yuv_planes.y[pixel_ptr_bit], &this->yuv_planes.u[pixel_ptr_bit], + &this->yuv_planes.v[pixel_ptr_bit], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + rowworkptr++; + data++; + } + } + + + + + size = _X_BE_16(ptr); + ptr++; + if (size < 0) { + for (s = size; s < 0; s++) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_SHORT( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + rowworkptr += rowsize_all_planes; + row_ptr++; + } + data++; + } + else { + for (s = 0; s < size; s++) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_SHORT( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + data++; + rowworkptr += rowsize_all_planes; + row_ptr++; + } + } + } + } + } +} + +/* decoding method 4 */ +static void bitplane_set_dlta_short (bitplane_decoder_t *this) { + + uint32_t rowsize = this->width / 16; + uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; + + uint32_t palette_index = 0; + uint32_t *deltadata = (uint32_t *)this->buf; + uint16_t *ptr = NULL; + uint16_t *planeptr = NULL; + uint16_t *picture_end = (uint16_t *)(&this->buf_uk[(rowsize_all_planes * 2 * this->height)]); + uint16_t *data = NULL; + uint16_t *data_end = (uint16_t *)(&this->buf[this->size]); + uint16_t *rowworkptr = NULL; + int16_t s = 0; + int16_t size = 0; + uint16_t pixel_ptr = 0; + uint32_t pixel_ptr_bit = 0; + uint32_t row_ptr = 0; + uint32_t yuv_index = 0; + + /* Repeat for each plane */ + for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { + + planeptr = (uint16_t *)(&this->buf_uk[(palette_index * rowsize * 2)]); + /* data starts at beginn of delta-Buffer + offset of the first */ + /* 32 Bit long word in the buffer. The buffer starts with 8 */ + /* of this Offset, for every bitplane (max 8) one */ + data = (uint16_t *)(&this->buf[_X_BE_32(&deltadata[palette_index])]); + if( data != (uint16_t *)this->buf ) { + /* This 8 Pointers are followd by another 8 */ + ptr = (uint16_t *)(&this->buf[_X_BE_32(&deltadata[(palette_index+8)])]); + + /* in this case, I think big/little endian is not important ;-) */ + while( *ptr != 0xFFFF) { + pixel_ptr = _X_BE_16(ptr); + pixel_ptr_bit = pixel_ptr * 16; + row_ptr = 0; + rowworkptr = planeptr + pixel_ptr; + ptr++; + size = _X_BE_16(ptr); + ptr++; + if (size < 0) { + for (s = size; s < 0; s++) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_SHORT( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + rowworkptr += rowsize_all_planes; + row_ptr++; + } + data++; + } else { + for (s = 0; s < size; s++) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_SHORT( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + data++; + rowworkptr += rowsize_all_planes; + row_ptr++; + } + } + } + } + } +} + +/* decoding method 5 */ +static void bitplane_dlta_5 (bitplane_decoder_t *this) { + + uint32_t rowsize = this->width / 8; + uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; + + uint32_t yuv_index = 0; + uint32_t delta_offset = 0; + uint32_t palette_index = 0; + uint32_t pixel_ptr = 0; + uint32_t pixel_ptr_bit = 0; + uint32_t row_ptr = 0; + uint32_t *deltadata = (uint32_t *)this->buf; + uint8_t *planeptr = NULL; + uint8_t *rowworkptr = NULL; + uint8_t *picture_end = this->buf_uk + (rowsize_all_planes * this->height); + uint8_t *data = NULL; + uint8_t *data_end = this->buf + this->size; + uint8_t op_count = 0; + uint8_t op = 0; + uint8_t count = 0; + + /* Repeat for each plane */ + for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { + + planeptr = &this->buf_uk[(palette_index * rowsize)]; + /* data starts at beginn of delta-Buffer + offset of the first */ + /* 32 Bit long word in the buffer. The buffer starts with 8 */ + /* of this Offset, for every bitplane (max 8) one */ + delta_offset = _X_BE_32(&deltadata[palette_index]); + + if (delta_offset > 0) { + data = this->buf + delta_offset; + for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { + rowworkptr = planeptr + pixel_ptr; + pixel_ptr_bit = pixel_ptr * 8; + row_ptr = 0; + /* execute ops */ + for( op_count = *data++; op_count; op_count--) { + op = *data++; + if (op & 0x80) { + /* Uniq ops */ + count = op & 0x7f; /* get count */ + while(count--) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_BYTE_SIMPLE(&this->index_buf[yuv_index], + *rowworkptr, *data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_BYTE( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + *rowworkptr, *data, bitplainoffeset[palette_index] ); + } + data++; + rowworkptr += rowsize_all_planes; + row_ptr++; + } + } else { + if (op == 0) { + /* Same ops */ + count = *data++; + while(count--) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_BYTE_SIMPLE(&this->index_buf[yuv_index], + *rowworkptr, *data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_BYTE( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + *rowworkptr, *data, bitplainoffeset[palette_index] ); + } + rowworkptr += rowsize_all_planes; + row_ptr++; + } + data++; + } else { + /* Skip ops */ + rowworkptr += (rowsize_all_planes * op); + row_ptr += op; + } + } + } + } + } + } +} + +/* decoding method 7 (short version) */ +static void bitplane_dlta_7_short (bitplane_decoder_t *this) { + + uint32_t rowsize = this->width / 16; + uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; + + uint32_t yuv_index = 0; + uint32_t opcode_offset = 0; + uint32_t data_offset = 0; + uint32_t palette_index = 0; + uint32_t pixel_ptr = 0; + uint32_t pixel_ptr_bit = 0; + uint32_t row_ptr = 0; + uint32_t *deltadata = (uint32_t *)this->buf; + uint8_t *planeptr = NULL; + uint16_t *rowworkptr = NULL; + uint16_t *picture_end = (uint16_t *)(&this->buf_uk[(rowsize_all_planes * 2 * this->height)]); + uint16_t *data = NULL; + uint16_t *data_end = (uint16_t *)(&this->buf[this->size]); + uint8_t *op_ptr = NULL; + uint8_t op_count = 0; + uint8_t op = 0; + uint8_t count = 0; + + /* Repeat for each plane */ + for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { + + planeptr = &this->buf_uk[(palette_index * rowsize * 2)]; + /* find opcode and data offset (up to 8 pointers, one for every bitplane */ + opcode_offset = _X_BE_32(&deltadata[palette_index]); + data_offset = _X_BE_32(&deltadata[palette_index + 8]); + + if (opcode_offset > 0 && data_offset > 0) { + data = (uint16_t *)(&this->buf[data_offset]); + op_ptr = this->buf + opcode_offset; + for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { + rowworkptr = (uint16_t *)(&planeptr[pixel_ptr * 2]); + pixel_ptr_bit = pixel_ptr * 16; + row_ptr = 0; + /* execute ops */ + for( op_count = *op_ptr++; op_count; op_count--) { + op = *op_ptr++; + if (op & 0x80) { + /* Uniq ops */ + count = op & 0x7f; /* get count */ + while(count--) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_SHORT( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + data++; + rowworkptr += rowsize_all_planes; + row_ptr++; + } + } else { + if (op == 0) { + /* Same ops */ + count = *op_ptr++; + while(count--) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_SHORT( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + rowworkptr += rowsize_all_planes; + row_ptr++; + } + data++; + } else { + /* Skip ops */ + rowworkptr += (rowsize_all_planes * op); + row_ptr += op; + } + } + } + } + } + } +} + +/* decoding method 7 (long version) */ +static void bitplane_dlta_7_long (bitplane_decoder_t *this) { + + uint32_t rowsize = this->width / 32; + uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; + + uint32_t yuv_index = 0; + uint32_t opcode_offset = 0; + uint32_t data_offset = 0; + uint32_t palette_index = 0; + uint32_t pixel_ptr = 0; + uint32_t pixel_ptr_bit = 0; + uint32_t row_ptr = 0; + uint32_t *deltadata = (uint32_t *)this->buf; + uint8_t *planeptr = NULL; + uint32_t *rowworkptr = NULL; + uint32_t *picture_end = (uint32_t *)(&this->buf_uk[(rowsize_all_planes * 4 * this->height)]); + uint32_t *data = NULL; + uint32_t *data_end = (uint32_t *)(&this->buf[this->size]); + uint8_t *op_ptr = NULL; + uint8_t op_count = 0; + uint8_t op = 0; + uint8_t count = 0; + + /* Repeat for each plane */ + for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { + planeptr = &this->buf_uk[(palette_index * rowsize * 4)]; + /* find opcode and data offset (up to 8 pointers, one for every bitplane */ + opcode_offset = _X_BE_32(&deltadata[palette_index]); + data_offset = _X_BE_32(&deltadata[palette_index + 8]); + + if (opcode_offset > 0 && data_offset > 0) { + data = (uint32_t *)(&this->buf[data_offset]); + op_ptr = this->buf + opcode_offset; + for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { + rowworkptr = (uint32_t *)(&planeptr[pixel_ptr * 4]); + pixel_ptr_bit = pixel_ptr * 32; + row_ptr = 0; + /* execute ops */ + for( op_count = *op_ptr++; op_count; op_count--) { + op = *op_ptr++; + if (op & 0x80) { + /* Uniq ops */ + count = op & 0x7f; /* get count */ + while(count--) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_LONG_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_LONG( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + data++; + rowworkptr += rowsize_all_planes; + row_ptr++; + } + } else { + if (op == 0) { + /* Same ops */ + count = *op_ptr++; + while(count--) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_LONG_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_LONG( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + rowworkptr += rowsize_all_planes; + row_ptr++; + } + data++; + } else { + /* Skip ops */ + rowworkptr += (rowsize_all_planes * op); + row_ptr += op; + } + } + } + } + } + } +} + +/* decoding method 8 short */ +static void bitplane_dlta_8_short (bitplane_decoder_t *this) { + + uint32_t rowsize = this->width / 16; + uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; + + uint32_t yuv_index = 0; + uint32_t delta_offset = 0; + uint32_t palette_index = 0; + uint32_t pixel_ptr = 0; + uint32_t row_ptr = 0; + uint32_t pixel_ptr_bit = 0; + uint32_t *deltadata = (uint32_t *)this->buf; + uint16_t *planeptr = NULL; + uint16_t *rowworkptr = NULL; + uint16_t *picture_end = (uint16_t *)(&this->buf_uk[(rowsize_all_planes * 2 * this->height)]); + uint16_t *data = NULL; + uint16_t *data_end = (uint16_t *)(&this->buf[this->size]); + uint16_t op_count = 0; + uint16_t op = 0; + uint16_t count = 0; + + /* Repeat for each plane */ + for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { + + planeptr = (uint16_t *)(&this->buf_uk[(palette_index * rowsize * 2)]); + /* data starts at beginn of delta-Buffer + offset of the first */ + /* 32 Bit long word in the buffer. The buffer starts with 8 */ + /* of this Offset, for every bitplane (max 8) one */ + delta_offset = _X_BE_32(&deltadata[palette_index]); + + if (delta_offset > 0) { + data = (uint16_t *)(&this->buf[delta_offset]); + for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { + rowworkptr = planeptr + pixel_ptr; + pixel_ptr_bit = pixel_ptr * 16; + row_ptr = 0; + /* execute ops */ + op_count = _X_BE_16(data); + data++; + for( ; op_count; op_count--) { + op = _X_BE_16(data); + data++; + if (op & 0x8000) { + /* Uniq ops */ + count = op & 0x7fff; /* get count */ + while(count--) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_SHORT( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + data++; + rowworkptr += rowsize_all_planes; + row_ptr++; + } + } else { + if (op == 0) { + /* Same ops */ + count = _X_BE_16(data); + data++; + while(count--) { + if (data > data_end || rowworkptr > picture_end) + return; + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_SHORT( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + rowworkptr += rowsize_all_planes; + row_ptr++; + } + data++; + } else { + /* Skip ops */ + rowworkptr += (rowsize_all_planes * op); + row_ptr += op; + } + } + } + } + } + } +} + +/* decoding method 8 long */ +static void bitplane_dlta_8_long (bitplane_decoder_t *this) { + + uint32_t rowsize = this->width / 32; + uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; + + uint32_t yuv_index = 0; + uint32_t delta_offset = 0; + uint32_t palette_index = 0; + uint32_t pixel_ptr = 0; + uint32_t pixel_ptr_bit = 0; + uint32_t row_ptr = 0; + uint32_t *deltadata = (uint32_t *)this->buf; + uint32_t *planeptr = NULL; + uint32_t *rowworkptr = NULL; + uint32_t *picture_end = (uint32_t *)(&this->buf_uk[(rowsize_all_planes * 4 * this->height)]); + uint32_t *data = NULL; + uint32_t *data_end = (uint32_t *)(&this->buf[this->size]); + uint32_t op_count = 0; + uint32_t op = 0; + uint32_t count = 0; + + /* Repeat for each plane */ + for(palette_index = 0; palette_index < this->num_bitplanes; palette_index++) { + + planeptr = (uint32_t *)(&this->buf_uk[(palette_index * rowsize * 4)]); + /* data starts at beginn of delta-Buffer + offset of the first */ + /* 32 Bit long word in the buffer. The buffer starts with 8 */ + /* of this Offset, for every bitplane (max 8) one */ + delta_offset = _X_BE_32(&deltadata[palette_index]); + + if (delta_offset > 0) { + data = (uint32_t *)(&this->buf[delta_offset]); + for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { + rowworkptr = planeptr + pixel_ptr; + pixel_ptr_bit = pixel_ptr * 32; + row_ptr = 0; + /* execute ops */ + op_count = _X_BE_32(data); + data++; + for( ; op_count; op_count--) { + op = _X_BE_32(data); + data++; + if (op & 0x80000000) { + /* Uniq ops */ + count = op & 0x7fffffff; /* get count */ + while(count--) { + if (data <= data_end || rowworkptr <= picture_end) { + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_LONG_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_LONG( &this->index_buf[((row_ptr * this->width) + pixel_ptr_bit)], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + } + data++; + rowworkptr += rowsize_all_planes; + row_ptr++; + } + } else { + if (op == 0) { + /* Same ops */ + count = _X_BE_32(data); + data++; + while(count--) { + if (data <= data_end && rowworkptr <= picture_end) { + yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); + if( this->is_ham ) { + IFF_REPLACE_LONG_SIMPLE(&this->index_buf[yuv_index], + rowworkptr, data, bitplainoffeset[palette_index] ); + } else { + IFF_REPLACE_LONG( &this->index_buf[yuv_index], + &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], + &this->yuv_planes.v[yuv_index], this->yuv_palette, + rowworkptr, data, bitplainoffeset[palette_index] ); + } + } + rowworkptr += rowsize_all_planes; + row_ptr++; + } + data++; + } else { + /* Skip ops */ + rowworkptr += (rowsize_all_planes * op); + row_ptr += op; + } + } + } + } + } + } +/* bitplane_decode_bitplane(this->buf_uk, this->index_buf, this->width, this->height, this->num_bitplanes, 1);*/ +} + +static void bitplane_decode_data (video_decoder_t *this_gen, + buf_element_t *buf) { + + bitplane_decoder_t *this = (bitplane_decoder_t *) this_gen; + xine_bmiheader *bih = 0; + palette_entry_t *palette = 0; + AnimHeader *anhd = NULL; + int i = 0; + int j = 0; + int buf_ptr = 0; + unsigned char r = 0; + unsigned char g = 0; + unsigned char b = 0; + uint8_t *buf_exchange = NULL; + + vo_frame_t *img = 0; /* video out frame */ + + /* a video decoder does not care about this flag (?) */ + if (buf->decoder_flags & BUF_FLAG_PREVIEW) + return; + + if ((buf->decoder_flags & BUF_FLAG_SPECIAL) && + (buf->decoder_info[1] == BUF_SPECIAL_PALETTE)) { + palette = (palette_entry_t *)buf->decoder_info_ptr[2]; + + for (i = 0; i < buf->decoder_info[2]; i++) { + this->yuv_palette[i * 4 + 0] = + COMPUTE_Y(palette[i].r, palette[i].g, palette[i].b); + this->yuv_palette[i * 4 + 1] = + COMPUTE_U(palette[i].r, palette[i].g, palette[i].b); + this->yuv_palette[i * 4 + 2] = + COMPUTE_V(palette[i].r, palette[i].g, palette[i].b); + this->rgb_palette[i * 4 + 0] = palette[i].r; + this->rgb_palette[i * 4 + 1] = palette[i].g; + this->rgb_palette[i * 4 + 2] = palette[i].b; + } + + /* EHB Pictures not allways contain all 64 colors, sometimes only */ + /* the first 32 are included and sometimes all 64 colors are provide,*/ + /* but second 32 are only stupid dirt, so recalculate them */ + if (((this->num_bitplanes == 6) && + (buf->decoder_info[2] == 32)) || + (this->camg_mode & CAMG_EHB)) { + for (i = 32; i < 64; i++) { + this->rgb_palette[i * 4 + 0] = palette[(i-32)].r / 2; + this->rgb_palette[i * 4 + 1] = palette[(i-32)].g / 2; + this->rgb_palette[i * 4 + 2] = palette[(i-32)].b / 2; + this->yuv_palette[i * 4 + 0] = + COMPUTE_Y(this->rgb_palette[i*4+0], this->rgb_palette[i*4+1], this->rgb_palette[i*4+2]); + this->yuv_palette[i * 4 + 1] = + COMPUTE_U(this->rgb_palette[i*4+0], this->rgb_palette[i*4+1], this->rgb_palette[i*4+2]); + this->yuv_palette[i * 4 + 2] = + COMPUTE_V(this->rgb_palette[i*4+0], this->rgb_palette[i*4+1], this->rgb_palette[i*4+2]); + } + } + + return; + } + + if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ + (this->stream->video_out->open) (this->stream->video_out, this->stream); + + bih = (xine_bmiheader *) buf->content; + this->width = (bih->biWidth + 15) & ~0x0f; + this->height = bih->biHeight; + this->num_pixel = this->width * this->height; + this->ratio = (double)this->width/(double)this->height; + this->video_step = buf->decoder_info[1]; + /* Palette based Formates use up to 8 Bit per pixel, always use 8 Bit if less */ + this->bytes_per_pixel = (bih->biBitCount + 1) / 8; + if( this->bytes_per_pixel < 1 ) + this->bytes_per_pixel = 1; + + /* New Buffer for indexes (palette based formats) */ + this->index_buf = xine_xcalloc( this->num_pixel, this->bytes_per_pixel ); + this->index_buf_hist = xine_xcalloc( this->num_pixel, this->bytes_per_pixel ); + + this->num_bitplanes = bih->biPlanes; + this->camg_mode = bih->biCompression; + if( this->camg_mode & CAMG_HAM ) + this->is_ham = 1; + else + this->is_ham = 0; + + if( buf->decoder_info[2] != buf->decoder_info[3] && + buf->decoder_info[3] > 0 ) { + this->ratio *= buf->decoder_info[2]; + this->ratio /= buf->decoder_info[3]; + } + + if( (bih->biCompression & CAMG_HIRES) && + !(bih->biCompression & CAMG_LACE) ) { + if( (buf->decoder_info[2] * 16) > (buf->decoder_info[3] * 10) ) + this->ratio /= 2.0; + } + + if( !(bih->biCompression & CAMG_HIRES) && + (bih->biCompression & CAMG_LACE) ) { + if( (buf->decoder_info[2] * 10) < (buf->decoder_info[3] * 16) ) + this->ratio *= 2.0; + } + + free (this->buf); + this->bufsize = VIDEOBUFSIZE; + this->buf = xine_xmalloc(this->bufsize); + this->size = 0; + this->framenumber = 0; + + init_yuv_planes(&this->yuv_planes, this->width, this->height); + init_yuv_planes(&this->yuv_planes_hist, this->width, this->height); + + (this->stream->video_out->open) (this->stream->video_out, this->stream); + this->decoder_ok = 1; + + /* load the stream/meta info */ + switch( buf->type ) { + case BUF_VIDEO_BITPLANE: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Uncompressed bitplane"); + break; + case BUF_VIDEO_BITPLANE_BR1: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "ByteRun1 bitplane"); + break; + default: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Unknown bitplane"); + break; + } + + return; + } else if (this->decoder_ok) { + + this->skipframes = 0; + this->framenumber++; + if (this->size + buf->size > this->bufsize) { + this->bufsize = this->size + 2 * buf->size; + this->buf = realloc (this->buf, this->bufsize); + } + + xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); + + this->size += buf->size; + + if (buf->decoder_flags & BUF_FLAG_FRAMERATE) + this->video_step = buf->decoder_info[0]; + + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { + + img = this->stream->video_out->get_frame (this->stream->video_out, + this->width, this->height, + this->ratio, XINE_IMGFMT_YUY2, + VO_BOTH_FIELDS); + + img->duration = this->video_step; + img->pts = buf->pts; + img->bad_frame = 0; + anhd = (AnimHeader *)(buf->decoder_info_ptr[0]); + + if( (this->buf_uk == NULL) || + (anhd == NULL) || + (anhd->operation == IFF_ANHD_ILBM) ) { + + /* iterate through each row */ + buf_ptr = 0; + this->size_uk = (((this->num_pixel) / 8) * this->num_bitplanes); + + if( this->buf_uk_hist != NULL ) + xine_fast_memcpy (this->buf_uk_hist, this->buf_uk, this->size_uk); + switch( buf->type ) { + case BUF_VIDEO_BITPLANE: + /* uncompressed Buffer, set decoded_buf pointer direct to input stream */ + if( this->buf_uk == NULL ) + this->buf_uk = xine_xmalloc( (this->size) ); + xine_fast_memcpy (this->buf_uk, this->buf, this->size); + break; + case BUF_VIDEO_BITPLANE_BR1: + /* create Buffer for decompressed bitmap */ + this->buf_uk = bitplane_decode_byterun1( + this->buf, /* compressed buffer */ + this->size, /* size of compressed data */ + this->size_uk ); /* size of uncompressed data */ + + if( this->buf_uk == NULL ) { + xine_log(this->stream->xine, XINE_LOG_MSG, + _("bitplane: error doing ByteRun1 decompression\n")); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); + return; + } + /* set pointer to decompressed Buffer */ + break; + default: + break; + } + bitplane_decode_bitplane( this->buf_uk, /* bitplane buffer */ + this->index_buf, /* index buffer */ + this->width, /* width */ + this->height, /* hight */ + this->num_bitplanes, /* number bitplanes */ + this->bytes_per_pixel); /* used Bytes per pixel */ + + if ((this->bytes_per_pixel == 1) && + (this->is_ham == 0) ) { + buf_exchange = this->index_buf; + for (i = 0; i < (this->height * this->width); i++) { + j = *buf_exchange++ * 4; + this->yuv_planes.y[i] = this->yuv_palette[j++]; + this->yuv_planes.u[i] = this->yuv_palette[j++]; + this->yuv_planes.v[i] = this->yuv_palette[j]; + } + } + if( this->buf_uk_hist == NULL ) { + this->buf_uk_hist = xine_xmalloc( (this->size_uk) ); + xine_fast_memcpy (this->buf_uk_hist, this->buf_uk, this->size_uk); + xine_fast_memcpy (this->index_buf_hist, this->index_buf, + (this->num_pixel * this->bytes_per_pixel)); + xine_fast_memcpy (this->yuv_planes_hist.y, this->yuv_planes.y, (this->num_pixel)); + xine_fast_memcpy (this->yuv_planes_hist.u, this->yuv_planes.u, (this->num_pixel)); + xine_fast_memcpy (this->yuv_planes_hist.v, this->yuv_planes.v, (this->num_pixel)); + } + } else { + /* when no start-picture is given, create a empty one */ + if( this->buf_uk_hist == NULL ) { + this->size_uk = (((this->num_pixel) / 8) * this->num_bitplanes); + this->buf_uk = xine_xmalloc( (this->size_uk) ); + this->buf_uk_hist = xine_xmalloc( (this->size_uk) ); + for (i = 0; i < this->size_uk; i++) { + this->buf_uk[i] = 0; + this->buf_uk_hist[i] = 0; + } + } + if( this->index_buf == NULL ) { + this->index_buf = xine_xcalloc( this->num_pixel, this->bytes_per_pixel ); + this->index_buf_hist = xine_xcalloc( this->num_pixel, this->bytes_per_pixel ); + for (i = 0; i < (this->num_pixel * this->bytes_per_pixel); i++) { + this->index_buf[i] = 0; + this->index_buf_hist[i] = 0; + } + } + + switch( anhd->operation ) { + /* also known as IFF-ANIM OPT1 (never seen in real world) */ + case IFF_ANHD_XOR: + xine_log(this->stream->xine, XINE_LOG_MSG, + _("bitplane: Anim Opt 1 is not supported at the moment\n")); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); + return; + break; + /* also known as IFF-ANIM OPT2 (never seen in real world) */ + case IFF_ANHD_LDELTA: + xine_log(this->stream->xine, XINE_LOG_MSG, + _("bitplane: Anim Opt 2 is not supported at the moment\n")); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); + return; + break; + /* also known as IFF-ANIM OPT3 */ + case IFF_ANHD_SDELTA: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT3"); + bitplane_sdelta_opt_3 ( this ); + return; + break; + /* also known as IFF-ANIM OPT4 (never seen in real world) */ + case IFF_ANHD_SLDELTA: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT4 (SLDELTA)"); + bitplane_set_dlta_short ( this ); + break; + /* also known as IFF-ANIM OPT5 */ + case IFF_ANHD_BVDELTA: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT5 (BVDELTA)"); + bitplane_dlta_5(this); + break; + /* IFF-ANIM OPT6 is exactly the same as OPT5, but for stereo-displays */ + /* first picture is on the left display, second on the right, third on */ + /* the left, forth on right, ... Only display left picture on mono display*/ + case IFF_ANHD_STEREOO5: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT6 (BVDELTA STEREO)"); + bitplane_dlta_5(this); + if( this->framenumber % 2 == 0 ) + this->skipframes = 1; + return; + break; + case IFF_ANHD_OPT7: + if(anhd->bits == 0) { + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT7 (SHORT)"); + bitplane_dlta_7_short(this); + } else { + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT7 (LONG)"); + bitplane_dlta_7_long(this); + } + break; + case IFF_ANHD_OPT8: + if(anhd->bits == 0) { + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT8 (SHORT)"); + bitplane_dlta_8_short(this); + } else { + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT8 (LONG)"); + bitplane_dlta_8_long(this); + } + break; + case IFF_ANHD_ASCIIJ: + xine_log(this->stream->xine, XINE_LOG_MSG, + _("bitplane: Anim ASCIIJ is not supported at the moment\n")); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); + return; + break; + default: + xine_log(this->stream->xine, XINE_LOG_MSG, + _("bitplane: This anim-type is not supported at the moment\n")); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); + return; + break; + } + /* change old bitmap buffer (which now is the new one) with new buffer */ + buf_exchange = this->buf_uk; + this->buf_uk = this->buf_uk_hist; + this->buf_uk_hist = buf_exchange; + /* do the same with the index buffer */ + buf_exchange = this->index_buf; + this->index_buf = this->index_buf_hist; + this->index_buf_hist = buf_exchange; + /* and also with yuv buffer */ + buf_exchange = this->yuv_planes.y; + this->yuv_planes.y = this->yuv_planes_hist.y; + this->yuv_planes_hist.y = buf_exchange; + buf_exchange = this->yuv_planes.u; + this->yuv_planes.u = this->yuv_planes_hist.u; + this->yuv_planes_hist.u = buf_exchange; + buf_exchange = this->yuv_planes.v; + this->yuv_planes.v = this->yuv_planes_hist.v; + this->yuv_planes_hist.v = buf_exchange; + } + + if( this->skipframes == 0 ) { + switch (this->bytes_per_pixel) { + case 1: + /* HAM-pictrues need special handling */ + if( this->is_ham ) { + /* Decode HAM-Pictures to YUV */ + bitplane_decode_ham( this->index_buf, /* HAM-bitplane buffer */ + &(this->yuv_planes), /* YUV buffer */ + this->width, /* width */ + this->height, /* hight */ + this->num_bitplanes, /* number bitplanes */ + this->bytes_per_pixel, /* used Bytes per pixel */ + this->rgb_palette); /* Palette (RGB) */ + } + break; + case 3: + buf_exchange = this->index_buf; + for (i = 0; i < (this->height * this->width); i++) { + r = *buf_exchange++; + g = *buf_exchange++; + b = *buf_exchange++; + + this->yuv_planes.y[i] = COMPUTE_Y(r, g, b); + this->yuv_planes.u[i] = COMPUTE_U(r, g, b); + this->yuv_planes.v[i] = COMPUTE_V(r, g, b); + } + break; + default: + break; + } + + yuv444_to_yuy2(&this->yuv_planes, img->base[0], img->pitches[0]); + + img->draw(img, this->stream); + } + img->free(img); + + this->size = 0; + if ( buf->decoder_info[1] > 90000 ) + xine_usec_sleep(buf->decoder_info[1]); + } + } +} + +/* + * This function is called when xine needs to flush the system. Not + * sure when or if this is used or even if it needs to do anything. + */ +static void bitplane_flush (video_decoder_t *this_gen) { +} + +/* + * This function resets the video decoder. + */ +static void bitplane_reset (video_decoder_t *this_gen) { + bitplane_decoder_t *this = (bitplane_decoder_t *) this_gen; + + this->size = 0; +} + +static void bitplane_discontinuity (video_decoder_t *this_gen) { +} + +/* + * This function frees the video decoder instance allocated to the decoder. + */ +static void bitplane_dispose (video_decoder_t *this_gen) { + bitplane_decoder_t *this = (bitplane_decoder_t *) this_gen; + + free (this->buf); + free (this->buf_uk); + free (this->buf_uk_hist); + free (this->index_buf); + free (this->index_buf_hist); + free (this->index_buf); + + if (this->decoder_ok) { + this->decoder_ok = 0; + this->stream->video_out->close(this->stream->video_out, this->stream); + } + + free (this_gen); +} + +static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { + + bitplane_decoder_t *this = (bitplane_decoder_t *) xine_xmalloc (sizeof (bitplane_decoder_t)); + + this->video_decoder.decode_data = bitplane_decode_data; + this->video_decoder.flush = bitplane_flush; + this->video_decoder.reset = bitplane_reset; + this->video_decoder.discontinuity = bitplane_discontinuity; + this->video_decoder.dispose = bitplane_dispose; + this->size = 0; + + this->stream = stream; + this->class = (bitplane_class_t *) class_gen; + + this->decoder_ok = 0; + this->buf = NULL; + this->buf_uk = NULL; + this->index_buf = NULL; + this->index_buf = NULL; + + return &this->video_decoder; +} + +static void *init_plugin (xine_t *xine, void *data) { + + bitplane_class_t *this = (bitplane_class_t *) xine_xmalloc (sizeof (bitplane_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "bitplane"; + this->decoder_class.description = N_("Raw bitplane video decoder plugin"); + this->decoder_class.dispose = default_video_decoder_class_dispose; + + return this; +} + +/* + * exported plugin catalog entry + */ + +static const uint32_t video_types[] = { + BUF_VIDEO_BITPLANE, + BUF_VIDEO_BITPLANE_BR1, + 0 +}; + +static const decoder_info_t dec_info_video = { + video_types, /* supported types */ + 1 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_VIDEO_DECODER, 19, "bitplane", XINE_VERSION_CODE, &dec_info_video, init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/video_dec/foovideo.c b/src/video_dec/foovideo.c new file mode 100644 index 000000000..49c63422c --- /dev/null +++ b/src/video_dec/foovideo.c @@ -0,0 +1,281 @@ +/* + * Copyright (C) 2000-2003 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * foovideo.c: This is a reference video decoder for the xine multimedia + * player. It really works too! It will output frames of packed YUY2 data + * where each byte in the map is the same value, which is 3 larger than the + * value from the last frame. This creates a slowly rotating solid color + * frame when the frames are played in succession. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "bswap.h" + +#define VIDEOBUFSIZE 128*1024 + +typedef struct { + video_decoder_class_t decoder_class; +} foovideo_class_t; + +typedef struct foovideo_decoder_s { + video_decoder_t video_decoder; /* parent video decoder structure */ + + foovideo_class_t *class; + xine_stream_t *stream; + + /* these are traditional variables in a video decoder object */ + uint64_t video_step; /* frame duration in pts units */ + int decoder_ok; /* current decoder status */ + int skipframes; + + unsigned char *buf; /* the accumulated buffer data */ + int bufsize; /* the maximum size of buf */ + int size; /* the current size of buf */ + + int width; /* the width of a video frame */ + int height; /* the height of a video frame */ + double ratio; /* the width to height ratio */ + + /* these are variables exclusive to the foo video decoder */ + unsigned char current_yuv_byte; + +} foovideo_decoder_t; + +/************************************************************************** + * foovideo specific decode functions + *************************************************************************/ + +/************************************************************************** + * xine video plugin functions + *************************************************************************/ + +/* + * This function receives a buffer of data from the demuxer layer and + * figures out how to handle it based on its header flags. + */ +static void foovideo_decode_data (video_decoder_t *this_gen, + buf_element_t *buf) { + + foovideo_decoder_t *this = (foovideo_decoder_t *) this_gen; + xine_bmiheader *bih; + + vo_frame_t *img; /* video out frame */ + + /* a video decoder does not care about this flag (?) */ + if (buf->decoder_flags & BUF_FLAG_PREVIEW) + return; + + if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { + this->video_step = buf->decoder_info[0]; + _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step); + } + + if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ + (this->stream->video_out->open) (this->stream->video_out, this->stream); + + free(this->buf); + + bih = (xine_bmiheader *) buf->content; + this->width = bih->biWidth; + this->height = bih->biHeight; + this->ratio = (double)this->width/(double)this->height; + + if (this->buf) + free (this->buf); + this->bufsize = VIDEOBUFSIZE; + this->buf = malloc(this->bufsize); + this->size = 0; + + /* take this opportunity to load the stream/meta info */ + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "foovideo"); + + /* do anything else relating to initializing this decoder */ + this->current_yuv_byte = 0; + + this->decoder_ok = 1; + + return; + } else if (this->decoder_ok) { + + if (this->size + buf->size > this->bufsize) { + this->bufsize = this->size + 2 * buf->size; + this->buf = realloc (this->buf, this->bufsize); + } + + xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); + + this->size += buf->size; + + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { + + img = this->stream->video_out->get_frame (this->stream->video_out, + this->width, this->height, + this->ratio, + XINE_IMGFMT_YUY2, VO_BOTH_FIELDS); + + img->duration = this->video_step; + img->pts = buf->pts; + img->bad_frame = 0; + + memset(img->base[0], this->current_yuv_byte, + this->width * this->height * 2); + this->current_yuv_byte += 3; + + img->draw(img, this->stream); + img->free(img); + + this->size = 0; + } + } +} + +/* + * This function is called when xine needs to flush the system. + */ +static void foovideo_flush (video_decoder_t *this_gen) { +} + +/* + * This function resets the video decoder. + */ +static void foovideo_reset (video_decoder_t *this_gen) { + foovideo_decoder_t *this = (foovideo_decoder_t *) this_gen; + + this->size = 0; +} + +/* + * The decoder should forget any stored pts values here. + */ +static void foovideo_discontinuity (video_decoder_t *this_gen) { + foovideo_decoder_t *this = (foovideo_decoder_t *) this_gen; + +} + +/* + * This function frees the video decoder instance allocated to the decoder. + */ +static void foovideo_dispose (video_decoder_t *this_gen) { + + foovideo_decoder_t *this = (foovideo_decoder_t *) this_gen; + + free (this->buf); + + if (this->decoder_ok) { + this->decoder_ok = 0; + this->stream->video_out->close(this->stream->video_out, this->stream); + } + + free (this_gen); +} + +/* + * This function allocates, initializes, and returns a private video + * decoder structure. + */ +static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { + + foovideo_decoder_t *this ; + + this = (foovideo_decoder_t *) xine_xmalloc (sizeof (foovideo_decoder_t)); + + this->video_decoder.decode_data = foovideo_decode_data; + this->video_decoder.flush = foovideo_flush; + this->video_decoder.reset = foovideo_reset; + this->video_decoder.discontinuity = foovideo_discontinuity; + this->video_decoder.dispose = foovideo_dispose; + this->size = 0; + + this->stream = stream; + this->class = (foovideo_class_t *) class_gen; + + this->decoder_ok = 0; + this->buf = NULL; + + return &this->video_decoder; +} + +/* + * This function frees the video decoder class and any other memory that was + * allocated. + */ +static void dispose_class (video_decoder_class_t *this) { + free (this); +} + +/* + * This function allocates a private video decoder class and initializes + * the class's member functions. + */ +static void *init_plugin (xine_t *xine, void *data) { + + foovideo_class_t *this; + + this = (foovideo_class_t *) xine_xmalloc (sizeof (foovideo_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "foovideo"; + this->decoder_class.description = N_("foovideo: reference xine video decoder plugin"); + this->decoder_class.dispose = dispose_class; + + return this; +} + +/* + * This is a list of all of the internal xine video buffer types that + * this decoder is able to handle. Check src/xine-engine/buffer.h for a + * list of valid buffer types (and add a new one if the one you need does + * not exist). Terminate the list with a 0. + */ +static const uint32_t video_types[] = { + /* BUF_VIDEO_FOOVIDEO, */ + BUF_VIDEO_VQA, + BUF_VIDEO_SORENSON_V3, + 0 +}; + +/* + * This data structure combines the list of supported xine buffer types and + * the priority that the plugin should be given with respect to other + * plugins that handle the same buffer type. A plugin with priority (n+1) + * will be used instead of a plugin with priority (n). + */ +static const decoder_info_t dec_info_video = { + video_types, /* supported types */ + 5 /* priority */ +}; + +/* + * The plugin catalog entry. This is the only information that this plugin + * will export to the public. + */ +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* { type, API, "name", version, special_info, init_function } */ + { PLUGIN_VIDEO_DECODER, 19, "foovideo", XINE_VERSION_CODE, &dec_info_video, init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/video_dec/gdkpixbuf.c b/src/video_dec/gdkpixbuf.c new file mode 100644 index 000000000..28c9c77c7 --- /dev/null +++ b/src/video_dec/gdkpixbuf.c @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2006 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * a gdk-pixbuf-based image video decoder + */ + + +#include +#include +#include +#include +#include +#include +#include + +#define LOG_MODULE "gdkpixbuf_video_decoder" +#define LOG_VERBOSE +/* +#define LOG +*/ + +#include +#include +#include +#include +#include "bswap.h" + +#include + +typedef struct { + video_decoder_class_t decoder_class; + + /* + * private variables + */ + +} image_class_t; + + +typedef struct image_decoder_s { + video_decoder_t video_decoder; + + image_class_t *cls; + + xine_stream_t *stream; + int video_open; + + GdkPixbufLoader *loader; + +} image_decoder_t; + + +static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { + image_decoder_t *this = (image_decoder_t *) this_gen; + GError *error = NULL; + + if (!this->video_open) { + lprintf("opening video\n"); + (this->stream->video_out->open) (this->stream->video_out, this->stream); + this->video_open = 1; + } + + if (this->loader == NULL) { + this->loader = gdk_pixbuf_loader_new (); + } + + if (gdk_pixbuf_loader_write (this->loader, buf->mem, buf->size, &error) == FALSE) { + lprintf("error loading image: %s\n", error->message); + g_error_free (error); + gdk_pixbuf_loader_close (this->loader, NULL); + g_object_unref (G_OBJECT (this->loader)); + this->loader = NULL; + return; + } + + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { + GdkPixbuf *pixbuf; + int width, height, x, y, rowstride, n_channels, i; + guchar *img_buf; + yuv_planes_t yuv_planes; + vo_frame_t *img; + + /* + * this->image -> rgb data + */ + if (gdk_pixbuf_loader_close (this->loader, &error) == FALSE) { + lprintf("error loading image: %s\n", error->message); + g_error_free (error); + g_object_unref (G_OBJECT (this->loader)); + this->loader = NULL; + return; + } + + pixbuf = gdk_pixbuf_loader_get_pixbuf (this->loader); + if (pixbuf != NULL) + g_object_ref (G_OBJECT (pixbuf)); + g_object_unref (this->loader); + this->loader = NULL; + + if (pixbuf == NULL) { + lprintf("error loading image\n"); + return; + } + + width = gdk_pixbuf_get_width (pixbuf) & ~1; /* must be even for init_yuv_planes */ + height = gdk_pixbuf_get_height (pixbuf); + img_buf = gdk_pixbuf_get_pixels (pixbuf); + + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, width); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, height); + + lprintf("image loaded successfully\n"); + + /* + * rgb data -> yuv_planes + */ + init_yuv_planes(&yuv_planes, width, height); + + n_channels = gdk_pixbuf_get_n_channels (pixbuf); + rowstride = gdk_pixbuf_get_rowstride (pixbuf); + i = 0; + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + guchar *p; + p = img_buf + y * rowstride + x * n_channels; + + yuv_planes.y[i] = COMPUTE_Y (p[0], p[1], p[2]); + yuv_planes.u[i] = COMPUTE_U (p[0], p[1], p[2]); + yuv_planes.v[i] = COMPUTE_V (p[0], p[1], p[2]); + + i++; + } + } + gdk_pixbuf_unref (pixbuf); + + /* + * alloc and draw video frame + */ + img = this->stream->video_out->get_frame (this->stream->video_out, width, + height, (double)width/(double)height, + XINE_IMGFMT_YUY2, + VO_BOTH_FIELDS); + img->pts = buf->pts; + img->duration = 3600; + img->bad_frame = 0; + + yuv444_to_yuy2(&yuv_planes, img->base[0], img->pitches[0]); + free_yuv_planes(&yuv_planes); + + _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, img->duration); + + img->draw(img, this->stream); + img->free(img); + } +} + + +static void image_flush (video_decoder_t *this_gen) { + /* image_decoder_t *this = (image_decoder_t *) this_gen; */ + + /* + * flush out any frames that are still stored in the decoder + */ +} + + +static void image_reset (video_decoder_t *this_gen) { + image_decoder_t *this = (image_decoder_t *) this_gen; + + /* + * reset decoder after engine flush (prepare for new + * video data not related to recently decoded data) + */ + + if (this->loader != NULL) { + gdk_pixbuf_loader_close (this->loader, NULL); + g_object_unref (G_OBJECT (this->loader)); + this->loader = NULL; + } +} + + +static void image_discontinuity (video_decoder_t *this_gen) { + /* image_decoder_t *this = (image_decoder_t *) this_gen; */ + + /* + * a time reference discontinuity has happened. + * that is, it must forget any currently held pts value + */ +} + +static void image_dispose (video_decoder_t *this_gen) { + image_decoder_t *this = (image_decoder_t *) this_gen; + + if (this->video_open) { + lprintf("closing video\n"); + + this->stream->video_out->close(this->stream->video_out, this->stream); + this->video_open = 0; + } + + if (this->loader != NULL) { + gdk_pixbuf_loader_close (this->loader, NULL); + g_object_unref (G_OBJECT (this->loader)); + this->loader = NULL; + } + + lprintf("closed\n"); + free (this); +} + + +static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, + xine_stream_t *stream) { + + image_class_t *cls = (image_class_t *) class_gen; + image_decoder_t *this; + + lprintf("opened\n"); + + g_type_init (); + + this = (image_decoder_t *) xine_xmalloc (sizeof (image_decoder_t)); + + this->video_decoder.decode_data = image_decode_data; + this->video_decoder.flush = image_flush; + this->video_decoder.reset = image_reset; + this->video_decoder.discontinuity = image_discontinuity; + this->video_decoder.dispose = image_dispose; + this->cls = cls; + this->stream = stream; + + /* + * initialisation of privates + */ + + return &this->video_decoder; +} + +/* + * image plugin class + */ +static void *init_class (xine_t *xine, void *data) { + + image_class_t *this; + + this = (image_class_t *) xine_xmalloc (sizeof (image_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "gdkpixbuf"; + this->decoder_class.description = N_("gdk-pixbuf image video decoder plugin"); + this->decoder_class.dispose = default_video_decoder_class_dispose; + + /* + * initialisation of privates + */ + + lprintf("class opened\n"); + + return this; +} + +/* + * exported plugin catalog entry + */ + +static uint32_t supported_types[] = { BUF_VIDEO_IMAGE, BUF_VIDEO_JPEG, 0 }; + +static const decoder_info_t dec_info_image = { + supported_types, /* supported types */ + 7 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_VIDEO_DECODER, 19, "gdkpixbuf", XINE_VERSION_CODE, &dec_info_image, init_class }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/video_dec/image.c b/src/video_dec/image.c new file mode 100644 index 000000000..e84312624 --- /dev/null +++ b/src/video_dec/image.c @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2003-2005 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * a image video decoder + */ + + +#include +#include +#include +#include +#include +#include +#include + +#define LOG_MODULE "image_video_decoder" +#define LOG_VERBOSE +/* +#define LOG +*/ + +#include +#ifdef PACKAGE_NAME +#undef PACKAGE_BUGREPORT +#undef PACKAGE_NAME +#undef PACKAGE_STRING +#undef PACKAGE_TARNAME +#undef PACKAGE_VERSION +#endif + +#include +#include +#include +#include +#include "bswap.h" + +typedef struct { + video_decoder_class_t decoder_class; + + /* + * private variables + */ + +} image_class_t; + + +typedef struct image_decoder_s { + video_decoder_t video_decoder; + + image_class_t *cls; + + xine_stream_t *stream; + int video_open; + + unsigned char *image; + int index; + +} image_decoder_t; + + +static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { + image_decoder_t *this = (image_decoder_t *) this_gen; + + if (!this->video_open) { + lprintf("opening video\n"); + (this->stream->video_out->open) (this->stream->video_out, this->stream); + this->video_open = 1; + } + + xine_buffer_copyin(this->image, this->index, buf->mem, buf->size); + this->index += buf->size; + + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { + int width, height, i; + MagickBooleanType status; + MagickWand *wand; + uint8_t *img_buf, *img_buf_ptr; + yuv_planes_t yuv_planes; + vo_frame_t *img; + + /* + * this->image -> rgb data + */ + wand = NewMagickWand(); + status = MagickReadImageBlob(wand, this->image, this->index); + this->index = 0; + + if (status == MagickFalse) { + DestroyMagickWand(wand); + lprintf("error loading image\n"); + return; + } + + width = MagickGetImageWidth(wand) & ~1; /* must be even for init_yuv_planes */ + height = MagickGetImageHeight(wand); + img_buf = malloc(width * height * 3); + MagickGetImagePixels(wand, 0, 0, width, height, "RGB", CharPixel, img_buf); + DestroyMagickWand(wand); + + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, width); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, height); + + lprintf("image loaded successfully\n"); + + /* + * rgb data -> yuv_planes + */ + init_yuv_planes(&yuv_planes, width, height); + + img_buf_ptr = img_buf; + for (i=0; i < width*height; i++) { + uint8_t r = *(img_buf_ptr++); + uint8_t g = *(img_buf_ptr++); + uint8_t b = *(img_buf_ptr++); + + yuv_planes.y[i] = COMPUTE_Y(r, g, b); + yuv_planes.u[i] = COMPUTE_U(r, g, b); + yuv_planes.v[i] = COMPUTE_V(r, g, b); + } + free(img_buf); + + /* + * alloc and draw video frame + */ + img = this->stream->video_out->get_frame (this->stream->video_out, width, + height, (double)width/(double)height, + XINE_IMGFMT_YUY2, + VO_BOTH_FIELDS); + img->pts = buf->pts; + img->duration = 3600; + img->bad_frame = 0; + + yuv444_to_yuy2(&yuv_planes, img->base[0], img->pitches[0]); + free_yuv_planes(&yuv_planes); + + _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, img->duration); + + img->draw(img, this->stream); + img->free(img); + } +} + + +static void image_flush (video_decoder_t *this_gen) { + /* image_decoder_t *this = (image_decoder_t *) this_gen; */ + + /* + * flush out any frames that are still stored in the decoder + */ +} + + +static void image_reset (video_decoder_t *this_gen) { + image_decoder_t *this = (image_decoder_t *) this_gen; + + /* + * reset decoder after engine flush (prepare for new + * video data not related to recently decoded data) + */ + + this->index = 0; +} + + +static void image_discontinuity (video_decoder_t *this_gen) { + /* image_decoder_t *this = (image_decoder_t *) this_gen; */ + + /* + * a time reference discontinuity has happened. + * that is, it must forget any currently held pts value + */ +} + +static void image_dispose (video_decoder_t *this_gen) { + image_decoder_t *this = (image_decoder_t *) this_gen; + + if (this->video_open) { + lprintf("closing video\n"); + + this->stream->video_out->close(this->stream->video_out, this->stream); + this->video_open = 0; + } + + xine_buffer_free(this->image); + + lprintf("closed\n"); + free (this); +} + + +static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, + xine_stream_t *stream) { + + image_class_t *cls = (image_class_t *) class_gen; + image_decoder_t *this; + + lprintf("opened\n"); + + this = (image_decoder_t *) xine_xmalloc (sizeof (image_decoder_t)); + + this->video_decoder.decode_data = image_decode_data; + this->video_decoder.flush = image_flush; + this->video_decoder.reset = image_reset; + this->video_decoder.discontinuity = image_discontinuity; + this->video_decoder.dispose = image_dispose; + this->cls = cls; + this->stream = stream; + + /* + * initialisation of privates + */ + + this->image = xine_buffer_init(10240); + + return &this->video_decoder; +} + +/* + * image plugin class + */ +static void *init_class (xine_t *xine, void *data) { + + image_class_t *this; + + this = (image_class_t *) xine_xmalloc (sizeof (image_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "imagevdec"; + this->decoder_class.description = N_("image video decoder plugin"); + this->decoder_class.dispose = default_video_decoder_class_dispose; + + /* + * initialisation of privates + */ + + lprintf("class opened\n"); + + return this; +} + +/* + * exported plugin catalog entry + */ + +static uint32_t supported_types[] = { BUF_VIDEO_IMAGE, + 0 }; + +static const decoder_info_t dec_info_image = { + supported_types, /* supported types */ + 6 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_VIDEO_DECODER, 19, "image", XINE_VERSION_CODE, &dec_info_image, init_class }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/video_dec/rgb.c b/src/video_dec/rgb.c new file mode 100644 index 000000000..9c8409e5f --- /dev/null +++ b/src/video_dec/rgb.c @@ -0,0 +1,447 @@ +/* + * Copyright (C) 2000-2003 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Raw RGB "Decoder" by Mike Melanson (melanson@pcisys.net) + * Actually, this decoder just converts a raw RGB image to a YUY2 map + * suitable for display under xine. + * + * This decoder deals with raw RGB data from Microsoft and Quicktime files. + * Data from a MS file can be 32-, 24-, 16-, or 8-bit. The latter can also + * be grayscale, depending on whether a palette is present. Data from a QT + * file can be 32-, 24-, 16-, 8-, 4-, 2-, or 1-bit. Any resolutions <= 8 + * can also be greyscale depending on what the QT file specifies. + * + * One more catch: Raw RGB from a Microsoft file is upside down. This is + * indicated by a negative height parameter. + */ + +#include +#include +#include +#include +#include + +#define LOG_MODULE "rgb" +#define LOG_VERBOSE +/* +#define LOG +*/ +#include +#include +#include +#include +#include "bswap.h" + +typedef struct { + video_decoder_class_t decoder_class; +} rgb_class_t; + +typedef struct rgb_decoder_s { + video_decoder_t video_decoder; /* parent video decoder structure */ + + rgb_class_t *class; + xine_stream_t *stream; + + /* these are traditional variables in a video decoder object */ + uint64_t video_step; /* frame duration in pts units */ + int decoder_ok; /* current decoder status */ + int skipframes; + + unsigned char *buf; /* the accumulated buffer data */ + int bufsize; /* the maximum size of buf */ + int size; /* the current size of buf */ + + int width; /* the width of a video frame */ + int height; /* the height of a video frame */ + double ratio; /* the width to height ratio */ + int bytes_per_pixel; + int bit_depth; + int upside_down; + + unsigned char yuv_palette[256 * 4]; + yuv_planes_t yuv_planes; + +} rgb_decoder_t; + +static void rgb_decode_data (video_decoder_t *this_gen, + buf_element_t *buf) { + + rgb_decoder_t *this = (rgb_decoder_t *) this_gen; + xine_bmiheader *bih; + palette_entry_t *palette; + int i; + int pixel_ptr, row_ptr; + int palette_index; + int buf_ptr; + unsigned int packed_pixel; + unsigned char r, g, b; + int pixels_left; + unsigned char pixel_byte = 0; + + vo_frame_t *img; /* video out frame */ + + /* a video decoder does not care about this flag (?) */ + if (buf->decoder_flags & BUF_FLAG_PREVIEW) + return; + + if ((buf->decoder_flags & BUF_FLAG_SPECIAL) && + (buf->decoder_info[1] == BUF_SPECIAL_PALETTE)) { + palette = (palette_entry_t *)buf->decoder_info_ptr[2]; + for (i = 0; i < buf->decoder_info[2]; i++) { + this->yuv_palette[i * 4 + 0] = + COMPUTE_Y(palette[i].r, palette[i].g, palette[i].b); + this->yuv_palette[i * 4 + 1] = + COMPUTE_U(palette[i].r, palette[i].g, palette[i].b); + this->yuv_palette[i * 4 + 2] = + COMPUTE_V(palette[i].r, palette[i].g, palette[i].b); + } + } + + if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { + this->video_step = buf->decoder_info[0]; + _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step); + } + + if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ + (this->stream->video_out->open) (this->stream->video_out, this->stream); + + bih = (xine_bmiheader *) buf->content; + this->width = (bih->biWidth + 3) & ~0x03; + this->height = (bih->biHeight + 3) & ~0x03; + if (this->height < 0) { + this->upside_down = 1; + this->height = -this->height; + } else { + this->upside_down = 0; + } + this->ratio = (double)this->width/(double)this->height; + + this->bit_depth = bih->biBitCount; + if (this->bit_depth > 32) + this->bit_depth &= 0x1F; + /* round this number up in case of 15 */ + lprintf("width = %d, height = %d, bit_depth = %d\n", this->width, this->height, this->bit_depth); + + this->bytes_per_pixel = (this->bit_depth + 1) / 8; + + free (this->buf); + + /* minimal buffer size */ + this->bufsize = this->width * this->height * this->bytes_per_pixel; + this->buf = xine_xmalloc(this->bufsize); + this->size = 0; + + init_yuv_planes(&this->yuv_planes, this->width, this->height); + + (this->stream->video_out->open) (this->stream->video_out, this->stream); + this->decoder_ok = 1; + + /* load the stream/meta info */ + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw RGB"); + + return; + } else if (this->decoder_ok) { + + if (this->size + buf->size > this->bufsize) { + this->bufsize = this->size + 2 * buf->size; + this->buf = realloc (this->buf, this->bufsize); + } + xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); + + this->size += buf->size; + + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { + + img = this->stream->video_out->get_frame (this->stream->video_out, + this->width, this->height, + this->ratio, XINE_IMGFMT_YUY2, + VO_BOTH_FIELDS); + + img->duration = this->video_step; + img->pts = buf->pts; + img->bad_frame = 0; + + + /* iterate through each row */ + buf_ptr = 0; + + if (this->upside_down) { + for (row_ptr = this->yuv_planes.row_width * (this->yuv_planes.row_count - 1); + row_ptr >= 0; row_ptr -= this->yuv_planes.row_width) { + for (pixel_ptr = 0; pixel_ptr < this->width; pixel_ptr++) { + + if (this->bytes_per_pixel == 1) { + + palette_index = this->buf[buf_ptr++]; + + this->yuv_planes.y[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 0]; + this->yuv_planes.u[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 1]; + this->yuv_planes.v[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 2]; + + } else if (this->bytes_per_pixel == 2) { + + /* ABGR1555 format, little-endian order */ + packed_pixel = _X_LE_16(&this->buf[buf_ptr]); + buf_ptr += 2; + UNPACK_BGR15(packed_pixel, r, g, b); + + this->yuv_planes.y[row_ptr + pixel_ptr] = + COMPUTE_Y(r, g, b); + this->yuv_planes.u[row_ptr + pixel_ptr] = + COMPUTE_U(r, g, b); + this->yuv_planes.v[row_ptr + pixel_ptr] = + COMPUTE_V(r, g, b); + + } else { + + /* BGR24 or BGRA32 */ + b = this->buf[buf_ptr++]; + g = this->buf[buf_ptr++]; + r = this->buf[buf_ptr++]; + + /* the next line takes care of 'A' in the 32-bit case */ + buf_ptr += this->bytes_per_pixel - 3; + + this->yuv_planes.y[row_ptr + pixel_ptr] = + COMPUTE_Y(r, g, b); + this->yuv_planes.u[row_ptr + pixel_ptr] = + COMPUTE_U(r, g, b); + this->yuv_planes.v[row_ptr + pixel_ptr] = + COMPUTE_V(r, g, b); + + } + } + } + } else { + + for (row_ptr = 0; row_ptr < this->yuv_planes.row_width * this->yuv_planes.row_count; row_ptr += this->yuv_planes.row_width) { + pixels_left = 0; + for (pixel_ptr = 0; pixel_ptr < this->width; pixel_ptr++) { + + if (this->bit_depth == 1) { + + if (pixels_left == 0) { + pixels_left = 8; + pixel_byte = *this->buf++; + } + + if (pixel_byte & 0x80) { + this->yuv_planes.y[row_ptr + pixel_ptr] = + this->yuv_palette[1 * 4 + 0]; + this->yuv_planes.u[row_ptr + pixel_ptr] = + this->yuv_palette[1 * 4 + 1]; + this->yuv_planes.v[row_ptr + pixel_ptr] = + this->yuv_palette[1 * 4 + 2]; + } else { + this->yuv_planes.y[row_ptr + pixel_ptr] = + this->yuv_palette[0 * 4 + 0]; + this->yuv_planes.u[row_ptr + pixel_ptr] = + this->yuv_palette[0 * 4 + 1]; + this->yuv_planes.v[row_ptr + pixel_ptr] = + this->yuv_palette[0 * 4 + 2]; + } + pixels_left--; + pixel_byte <<= 1; + + } else if (this->bit_depth == 2) { + + if (pixels_left == 0) { + pixels_left = 4; + pixel_byte = *this->buf++; + } + + palette_index = (pixel_byte & 0xC0) >> 6; + this->yuv_planes.y[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 0]; + this->yuv_planes.u[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 1]; + this->yuv_planes.v[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 2]; + + pixels_left--; + pixel_byte <<= 2; + + } else if (this->bit_depth == 4) { + + if (pixels_left == 0) { + pixels_left = 2; + pixel_byte = *this->buf++; + } + + palette_index = (pixel_byte & 0xF0) >> 4; + this->yuv_planes.y[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 0]; + this->yuv_planes.u[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 1]; + this->yuv_planes.v[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 2]; + + pixels_left--; + pixel_byte <<= 4; + + } else if (this->bytes_per_pixel == 1) { + + palette_index = this->buf[buf_ptr++]; + + this->yuv_planes.y[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 0]; + this->yuv_planes.u[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 1]; + this->yuv_planes.v[row_ptr + pixel_ptr] = + this->yuv_palette[palette_index * 4 + 2]; + + } else if (this->bytes_per_pixel == 2) { + + /* ARGB1555 format, big-endian order */ + packed_pixel = _X_BE_16(&this->buf[buf_ptr]); + buf_ptr += 2; + UNPACK_RGB15(packed_pixel, r, g, b); + + this->yuv_planes.y[row_ptr + pixel_ptr] = + COMPUTE_Y(r, g, b); + this->yuv_planes.u[row_ptr + pixel_ptr] = + COMPUTE_U(r, g, b); + this->yuv_planes.v[row_ptr + pixel_ptr] = + COMPUTE_V(r, g, b); + + } else { + + /* RGB24 or ARGB32; the next line takes care of 'A' in the + * 32-bit case */ + buf_ptr += this->bytes_per_pixel - 3; + + r = this->buf[buf_ptr++]; + g = this->buf[buf_ptr++]; + b = this->buf[buf_ptr++]; + + this->yuv_planes.y[row_ptr + pixel_ptr] = + COMPUTE_Y(r, g, b); + this->yuv_planes.u[row_ptr + pixel_ptr] = + COMPUTE_U(r, g, b); + this->yuv_planes.v[row_ptr + pixel_ptr] = + COMPUTE_V(r, g, b); + + } + } + } + } + + yuv444_to_yuy2(&this->yuv_planes, img->base[0], img->pitches[0]); + + img->draw(img, this->stream); + img->free(img); + + this->size = 0; + } + } +} + +/* + * This function is called when xine needs to flush the system. Not + * sure when or if this is used or even if it needs to do anything. + */ +static void rgb_flush (video_decoder_t *this_gen) { +} + +/* + * This function resets the video decoder. + */ +static void rgb_reset (video_decoder_t *this_gen) { + rgb_decoder_t *this = (rgb_decoder_t *) this_gen; + + this->size = 0; +} + +static void rgb_discontinuity (video_decoder_t *this_gen) { +} + +/* + * This function frees the video decoder instance allocated to the decoder. + */ +static void rgb_dispose (video_decoder_t *this_gen) { + rgb_decoder_t *this = (rgb_decoder_t *) this_gen; + + free (this->buf); + + if (this->decoder_ok) { + this->decoder_ok = 0; + this->stream->video_out->close(this->stream->video_out, this->stream); + } + + free (this_gen); +} + +static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { + + rgb_decoder_t *this ; + + this = (rgb_decoder_t *) xine_xmalloc (sizeof (rgb_decoder_t)); + + this->video_decoder.decode_data = rgb_decode_data; + this->video_decoder.flush = rgb_flush; + this->video_decoder.reset = rgb_reset; + this->video_decoder.discontinuity = rgb_discontinuity; + this->video_decoder.dispose = rgb_dispose; + this->size = 0; + + this->stream = stream; + this->class = (rgb_class_t *) class_gen; + + this->decoder_ok = 0; + this->buf = NULL; + + return &this->video_decoder; +} + +static void *init_plugin (xine_t *xine, void *data) { + + rgb_class_t *this; + + this = (rgb_class_t *) xine_xmalloc (sizeof (rgb_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "RGB"; + this->decoder_class.description = N_("Raw RGB video decoder plugin"); + this->decoder_class.dispose = default_video_decoder_class_dispose; + + return this; +} + +/* + * exported plugin catalog entry + */ + +static const uint32_t video_types[] = { + BUF_VIDEO_RGB, + 0 + }; + +static const decoder_info_t dec_info_video = { + video_types, /* supported types */ + 1 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_VIDEO_DECODER, 19, "rgb", XINE_VERSION_CODE, &dec_info_video, init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/video_dec/yuv.c b/src/video_dec/yuv.c new file mode 100644 index 000000000..c1e5825c5 --- /dev/null +++ b/src/video_dec/yuv.c @@ -0,0 +1,373 @@ +/* + * Copyright (C) 2000-2004 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * YUV "Decoder" by Mike Melanson (melanson@pcisys.net) + * Actually, this decoder just reorganizes chunks of raw YUV data in such + * a way that xine can display them. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "bswap.h" + +#define VIDEOBUFSIZE 128*1024 + +typedef struct { + video_decoder_class_t decoder_class; +} yuv_class_t; + +typedef struct yuv_decoder_s { + video_decoder_t video_decoder; /* parent video decoder structure */ + + yuv_class_t *class; + xine_stream_t *stream; + + /* these are traditional variables in a video decoder object */ + uint64_t video_step; /* frame duration in pts units */ + int decoder_ok; /* current decoder status */ + int skipframes; + + unsigned char *buf; /* the accumulated buffer data */ + int bufsize; /* the maximum size of buf */ + int size; /* the current size of buf */ + + int width; /* the width of a video frame */ + int height; /* the height of a video frame */ + double ratio; /* the width to height ratio */ + + int progressive; + int top_field_first; + +} yuv_decoder_t; + +/************************************************************************** + * xine video plugin functions + *************************************************************************/ + +/* + * This function receives a buffer of data from the demuxer layer and + * figures out how to handle it based on its header flags. + */ +static void yuv_decode_data (video_decoder_t *this_gen, + buf_element_t *buf) { + + yuv_decoder_t *this = (yuv_decoder_t *) this_gen; + xine_bmiheader *bih; + + vo_frame_t *img; /* video out frame */ + + /* a video decoder does not care about this flag (?) */ + if (buf->decoder_flags & BUF_FLAG_PREVIEW) + return; + + if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { + this->video_step = buf->decoder_info[0]; + _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step); + } + + if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ + (this->stream->video_out->open) (this->stream->video_out, this->stream); + + bih = (xine_bmiheader *) buf->content; + this->width = (bih->biWidth + 3) & ~0x03; + this->height = (bih->biHeight + 3) & ~0x03; + + if (buf->decoder_flags & BUF_FLAG_ASPECT) + this->ratio = (double)buf->decoder_info[1] / (double)buf->decoder_info[2]; + else + this->ratio = (double)this->width / (double)this->height; + + this->progressive = buf->decoder_info[3]; + this->top_field_first = buf->decoder_info[4]; + + free (this->buf); + this->buf = NULL; + + this->bufsize = VIDEOBUFSIZE; + this->buf = malloc(this->bufsize); + this->size = 0; + + this->decoder_ok = 1; + + /* load the stream/meta info */ + switch (buf->type) { + + case BUF_VIDEO_YUY2: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw YUY2"); + break; + + case BUF_VIDEO_YV12: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw YV12"); + break; + + case BUF_VIDEO_YVU9: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw YVU9"); + break; + + case BUF_VIDEO_GREY: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Greyscale YUV"); + break; + + case BUF_VIDEO_I420: + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw I420"); + break; + + } + + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->width); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->height); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, this->ratio*10000); + + return; + } else if (this->decoder_ok && !(buf->decoder_flags & BUF_FLAG_SPECIAL)) { + uint8_t *src; + + /* if buffer contains an entire frame then there's no need to copy it + * into our internal buffer */ + if ((buf->decoder_flags & BUF_FLAG_FRAME_START) && + (buf->decoder_flags & BUF_FLAG_FRAME_END)) + src = buf->content; + else { + if (this->size + buf->size > this->bufsize) { + this->bufsize = this->size + 2 * buf->size; + this->buf = realloc (this->buf, this->bufsize); + } + + xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); + + this->size += buf->size; + + src = this->buf; + } + + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { + + if (buf->type == BUF_VIDEO_YUY2) { + + img = this->stream->video_out->get_frame (this->stream->video_out, + this->width, this->height, + this->ratio, XINE_IMGFMT_YUY2, VO_BOTH_FIELDS); + + yuy2_to_yuy2( + /* src */ + src, this->width*2, + /* dst */ + img->base[0], img->pitches[0], + /* width x height */ + this->width, this->height); + + } else if (buf->type == BUF_VIDEO_YV12) { + + img = this->stream->video_out->get_frame (this->stream->video_out, + this->width, this->height, + this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); + + yv12_to_yv12( + /* Y */ + src, this->width, + img->base[0], img->pitches[0], + /* U */ + src + (this->width * this->height * 5/4), this->width/2, + img->base[1], img->pitches[1], + /* V */ + src + (this->width * this->height), this->width/2, + img->base[2], img->pitches[2], + /* width x height */ + this->width, this->height); + + } else if (buf->type == BUF_VIDEO_I420) { + + img = this->stream->video_out->get_frame (this->stream->video_out, + this->width, this->height, + this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); + + yv12_to_yv12( + /* Y */ + src, this->width, + img->base[0], img->pitches[0], + /* U */ + src + (this->width * this->height), this->width/2, + img->base[1], img->pitches[1], + /* V */ + src + (this->width * this->height * 5/4), this->width/2, + img->base[2], img->pitches[2], + /* width x height */ + this->width, this->height); + + } else if (buf->type == BUF_VIDEO_YVU9) { + + img = this->stream->video_out->get_frame (this->stream->video_out, + this->width, this->height, + this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); + + + yuv9_to_yv12( + /* Y */ + src, + this->width, + img->base[0], + img->pitches[0], + /* U */ + src + (this->width * this->height), + this->width / 4, + img->base[1], + img->pitches[1], + /* V */ + src + (this->width * this->height) + + (this->width * this->height / 16), + this->width / 4, + img->base[2], + img->pitches[2], + /* width x height */ + this->width, + this->height); + + } else if (buf->type == BUF_VIDEO_GREY) { + + img = this->stream->video_out->get_frame (this->stream->video_out, + this->width, this->height, + this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); + + xine_fast_memcpy(img->base[0], src, this->width * this->height); + memset( img->base[1], 0x80, this->width * this->height / 4 ); + memset( img->base[2], 0x80, this->width * this->height / 4 ); + + } else { + + /* just allocate something to avoid compiler warnings */ + img = this->stream->video_out->get_frame (this->stream->video_out, + this->width, this->height, + this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); + + } + + img->duration = this->video_step; + img->pts = buf->pts; + img->bad_frame = 0; + + img->draw(img, this->stream); + img->free(img); + + this->size = 0; + } + } +} + +/* + * This function is called when xine needs to flush the system. Not + * sure when or if this is used or even if it needs to do anything. + */ +static void yuv_flush (video_decoder_t *this_gen) { +} + +/* + * This function resets the video decoder. + */ +static void yuv_reset (video_decoder_t *this_gen) { + yuv_decoder_t *this = (yuv_decoder_t *) this_gen; + + this->size = 0; +} + +static void yuv_discontinuity (video_decoder_t *this_gen) { +} + +/* + * This function frees the video decoder instance allocated to the decoder. + */ +static void yuv_dispose (video_decoder_t *this_gen) { + yuv_decoder_t *this = (yuv_decoder_t *) this_gen; + + free (this->buf); + + if (this->decoder_ok) { + this->decoder_ok = 0; + this->stream->video_out->close(this->stream->video_out, this->stream); + } + + free (this_gen); +} + +static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { + + yuv_decoder_t *this ; + + this = (yuv_decoder_t *) xine_xmalloc (sizeof (yuv_decoder_t)); + + this->video_decoder.decode_data = yuv_decode_data; + this->video_decoder.flush = yuv_flush; + this->video_decoder.reset = yuv_reset; + this->video_decoder.discontinuity = yuv_discontinuity; + this->video_decoder.dispose = yuv_dispose; + this->size = 0; + + this->stream = stream; + this->class = (yuv_class_t *) class_gen; + + this->decoder_ok = 0; + this->buf = NULL; + + return &this->video_decoder; +} + +static void *init_plugin (xine_t *xine, void *data) { + + yuv_class_t *this; + + this = (yuv_class_t *) xine_xmalloc (sizeof (yuv_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.identifier = "YUV"; + this->decoder_class.description = N_("Raw YUV video decoder plugin"); + this->decoder_class.dispose = default_video_decoder_class_dispose; + + return this; +} + +/* + * exported plugin catalog entry + */ + +static const uint32_t video_types[] = { + BUF_VIDEO_YUY2, + BUF_VIDEO_YV12, + BUF_VIDEO_YVU9, + BUF_VIDEO_GREY, + BUF_VIDEO_I420, + 0 + }; + +static const decoder_info_t dec_info_video = { + video_types, /* supported types */ + 1 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_VIDEO_DECODER, 19, "yuv", XINE_VERSION_CODE, &dec_info_video, init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; -- cgit v1.2.3