2 Copyright (C) 2002-2013 DarkPlaces contributors
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include "dpvsimpledecode.h"
24 #define HZREADERROR_OK 0
25 #define HZREADERROR_EOF 1
26 #define HZREADERROR_MALLOCFAILED 2
28 //#define HZREADBLOCKSIZE 16000
29 #define HZREADBLOCKSIZE 1048576
31 typedef struct hz_bitstream_read_s
38 typedef struct hz_bitstream_readblock_s
40 struct hz_bitstream_readblock_s *next;
42 unsigned char data[HZREADBLOCKSIZE];
44 hz_bitstream_readblock_t;
46 typedef struct hz_bitstream_readblocks_s
48 hz_bitstream_readblock_t *blocks;
49 hz_bitstream_readblock_t *current;
50 unsigned int position;
54 hz_bitstream_readblocks_t;
56 static hz_bitstream_read_t *hz_bitstream_read_open(char *filename)
59 hz_bitstream_read_t *stream;
60 if ((file = FS_OpenVirtualFile(filename, false)))
62 stream = (hz_bitstream_read_t *)Z_Malloc(sizeof(hz_bitstream_read_t));
63 memset(stream, 0, sizeof(*stream));
71 static void hz_bitstream_read_close(hz_bitstream_read_t *stream)
75 FS_Close(stream->file);
80 static hz_bitstream_readblocks_t *hz_bitstream_read_blocks_new(void)
82 hz_bitstream_readblocks_t *blocks;
83 blocks = (hz_bitstream_readblocks_t *)Z_Malloc(sizeof(hz_bitstream_readblocks_t));
86 memset(blocks, 0, sizeof(hz_bitstream_readblocks_t));
90 static void hz_bitstream_read_blocks_free(hz_bitstream_readblocks_t *blocks)
92 hz_bitstream_readblock_t *b, *n;
95 for (b = blocks->blocks;b;b = n)
103 static void hz_bitstream_read_flushbits(hz_bitstream_readblocks_t *blocks)
109 static int hz_bitstream_read_blocks_read(hz_bitstream_readblocks_t *blocks, hz_bitstream_read_t *stream, unsigned int size)
112 hz_bitstream_readblock_t *b, *p;
120 b = (hz_bitstream_readblock_t *)Z_Malloc(sizeof(hz_bitstream_readblock_t));
122 return HZREADERROR_MALLOCFAILED;
130 if (s > HZREADBLOCKSIZE)
131 b->size = HZREADBLOCKSIZE;
135 if (FS_Read(stream->file, b->data, b->size) != (fs_offset_t)b->size)
137 stream->endoffile = 1;
148 blocks->current = blocks->blocks;
149 blocks->position = 0;
150 hz_bitstream_read_flushbits(blocks);
151 if (stream->endoffile)
152 return HZREADERROR_EOF;
153 return HZREADERROR_OK;
156 static unsigned int hz_bitstream_read_blocks_getbyte(hz_bitstream_readblocks_t *blocks)
158 while (blocks->current != NULL && blocks->position >= blocks->current->size)
160 blocks->position = 0;
161 blocks->current = blocks->current->next;
163 if (blocks->current == NULL)
165 return blocks->current->data[blocks->position++];
168 static int hz_bitstream_read_bit(hz_bitstream_readblocks_t *blocks)
174 blocks->store |= hz_bitstream_read_blocks_getbyte(blocks) & 0xFF;
177 return (blocks->store >> blocks->count) & 1;
180 static unsigned int hz_bitstream_read_bits(hz_bitstream_readblocks_t *blocks, int size)
182 unsigned int num = 0;
183 // we can only handle about 24 bits at a time safely
184 // (there might be up to 7 bits more than we need in the bit store)
188 num |= hz_bitstream_read_bits(blocks, 8) << size;
190 while (blocks->count < size)
194 blocks->store |= hz_bitstream_read_blocks_getbyte(blocks) & 0xFF;
196 blocks->count -= size;
197 num |= (blocks->store >> blocks->count) & ((1 << size) - 1);
201 static unsigned int hz_bitstream_read_byte(hz_bitstream_readblocks_t *blocks)
203 return hz_bitstream_read_blocks_getbyte(blocks);
206 static unsigned int hz_bitstream_read_short(hz_bitstream_readblocks_t *blocks)
208 return (hz_bitstream_read_byte(blocks) << 8)
209 | (hz_bitstream_read_byte(blocks));
212 static unsigned int hz_bitstream_read_int(hz_bitstream_readblocks_t *blocks)
214 return (hz_bitstream_read_byte(blocks) << 24)
215 | (hz_bitstream_read_byte(blocks) << 16)
216 | (hz_bitstream_read_byte(blocks) << 8)
217 | (hz_bitstream_read_byte(blocks));
220 static void hz_bitstream_read_bytes(hz_bitstream_readblocks_t *blocks, void *outdata, unsigned int size)
223 out = (unsigned char *)outdata;
225 *out++ = hz_bitstream_read_byte(blocks);
230 typedef struct dpvsimpledecodestream_s
232 hz_bitstream_read_t *bitstream;
233 hz_bitstream_readblocks_t *framedatablocks;
237 double info_framerate;
238 unsigned int info_frames;
240 unsigned int info_imagewidth;
241 unsigned int info_imageheight;
242 unsigned int info_imagebpp;
243 unsigned int info_imageRloss;
244 unsigned int info_imageRmask;
245 unsigned int info_imageRshift;
246 unsigned int info_imageGloss;
247 unsigned int info_imageGmask;
248 unsigned int info_imageGshift;
249 unsigned int info_imageBloss;
250 unsigned int info_imageBmask;
251 unsigned int info_imageBshift;
252 unsigned int info_imagesize;
253 double info_aspectratio;
255 // current video frame (needed because of delta compression)
257 // current video frame data (needed because of delta compression)
258 unsigned int *videopixels;
260 // channel the sound file is being played on
263 dpvsimpledecodestream_t;
265 static int dpvsimpledecode_setpixelformat(dpvsimpledecodestream_t *s, unsigned int Rmask, unsigned int Gmask, unsigned int Bmask, unsigned int bytesperpixel)
267 int Rshift, Rbits, Gshift, Gbits, Bshift, Bbits;
270 s->error = DPVSIMPLEDECODEERROR_INVALIDRMASK;
275 s->error = DPVSIMPLEDECODEERROR_INVALIDGMASK;
280 s->error = DPVSIMPLEDECODEERROR_INVALIDBMASK;
283 if (Rmask & Gmask || Rmask & Bmask || Gmask & Bmask)
285 s->error = DPVSIMPLEDECODEERROR_COLORMASKSOVERLAP;
288 switch (bytesperpixel)
291 if ((Rmask | Gmask | Bmask) > 65536)
293 s->error = DPVSIMPLEDECODEERROR_COLORMASKSEXCEEDBPP;
300 s->error = DPVSIMPLEDECODEERROR_UNSUPPORTEDBPP;
303 for (Rshift = 0;!(Rmask & 1);Rshift++, Rmask >>= 1);
304 for (Gshift = 0;!(Gmask & 1);Gshift++, Gmask >>= 1);
305 for (Bshift = 0;!(Bmask & 1);Bshift++, Bmask >>= 1);
306 if (((Rmask + 1) & Rmask) != 0)
308 s->error = DPVSIMPLEDECODEERROR_INVALIDRMASK;
311 if (((Gmask + 1) & Gmask) != 0)
313 s->error = DPVSIMPLEDECODEERROR_INVALIDGMASK;
316 if (((Bmask + 1) & Bmask) != 0)
318 s->error = DPVSIMPLEDECODEERROR_INVALIDBMASK;
321 for (Rbits = 0;Rmask & 1;Rbits++, Rmask >>= 1);
322 for (Gbits = 0;Gmask & 1;Gbits++, Gmask >>= 1);
323 for (Bbits = 0;Bmask & 1;Bbits++, Bmask >>= 1);
326 Rshift += (Rbits - 8);
331 Gshift += (Gbits - 8);
336 Bshift += (Bbits - 8);
339 s->info_imagebpp = bytesperpixel;
340 s->info_imageRloss = 16 + (8 - Rbits);
341 s->info_imageGloss = 8 + (8 - Gbits);
342 s->info_imageBloss = 0 + (8 - Bbits);
343 s->info_imageRmask = (1 << Rbits) - 1;
344 s->info_imageGmask = (1 << Gbits) - 1;
345 s->info_imageBmask = (1 << Bbits) - 1;
346 s->info_imageRshift = Rshift;
347 s->info_imageGshift = Gshift;
348 s->info_imageBshift = Bshift;
349 s->info_imagesize = s->info_imagewidth * s->info_imageheight * s->info_imagebpp;
353 // opening and closing streams
356 void *dpvsimpledecode_open(clvideo_t *video, char *filename, const char **errorstring)
358 dpvsimpledecodestream_t *s;
359 char t[8], *wavename;
360 if (errorstring != NULL)
362 s = (dpvsimpledecodestream_t *)Z_Malloc(sizeof(dpvsimpledecodestream_t));
365 s->bitstream = hz_bitstream_read_open(filename);
366 if (s->bitstream != NULL)
368 // check file identification
369 s->framedatablocks = hz_bitstream_read_blocks_new();
370 if (s->framedatablocks != NULL)
372 hz_bitstream_read_blocks_read(s->framedatablocks, s->bitstream, 8);
373 hz_bitstream_read_bytes(s->framedatablocks, t, 8);
374 if (!memcmp(t, "DPVideo", 8))
376 // check version number
377 hz_bitstream_read_blocks_read(s->framedatablocks, s->bitstream, 2);
378 if (hz_bitstream_read_short(s->framedatablocks) == 1)
380 hz_bitstream_read_blocks_read(s->framedatablocks, s->bitstream, 12);
381 s->info_imagewidth = hz_bitstream_read_short(s->framedatablocks);
382 s->info_imageheight = hz_bitstream_read_short(s->framedatablocks);
383 s->info_framerate = (double) hz_bitstream_read_int(s->framedatablocks) * (1.0 / 65536.0);
384 s->info_aspectratio = (double)s->info_imagewidth / (double)s->info_imageheight;
386 if (s->info_framerate > 0.0)
388 s->videopixels = (unsigned int *)Z_Malloc(s->info_imagewidth * s->info_imageheight * sizeof(*s->videopixels));
389 if (s->videopixels != NULL)
393 namelen = strlen(filename) + 10;
394 wavename = (char *)Z_Malloc(namelen);
399 FS_StripExtension(filename, wavename, namelen);
400 dp_strlcat(wavename, ".wav", namelen);
401 sfx = S_PrecacheSound (wavename, false, false);
403 s->sndchan = S_StartSound (-1, 0, sfx, vec3_origin, 1.0f, 0);
409 // set the module functions
410 s->videoframenum = -10000;
411 video->close = dpvsimpledecode_close;
412 video->getwidth = dpvsimpledecode_getwidth;
413 video->getheight = dpvsimpledecode_getheight;
414 video->getframerate = dpvsimpledecode_getframerate;
415 video->decodeframe = dpvsimpledecode_video;
416 video->getaspectratio = dpvsimpledecode_getaspectratio;
420 else if (errorstring != NULL)
421 *errorstring = "unable to allocate video image buffer";
423 else if (errorstring != NULL)
424 *errorstring = "error in video info chunk";
426 else if (errorstring != NULL)
427 *errorstring = "read error";
429 else if (errorstring != NULL)
430 *errorstring = "not a dpvideo file";
431 hz_bitstream_read_blocks_free(s->framedatablocks);
433 else if (errorstring != NULL)
434 *errorstring = "unable to allocate memory for reading buffer";
435 hz_bitstream_read_close(s->bitstream);
437 else if (errorstring != NULL)
438 *errorstring = "unable to open file";
441 else if (errorstring != NULL)
442 *errorstring = "unable to allocate memory for stream info structure";
447 void dpvsimpledecode_close(void *stream)
449 dpvsimpledecodestream_t *s = (dpvsimpledecodestream_t *)stream;
453 Z_Free(s->videopixels);
454 if (s->sndchan != -1)
455 S_StopChannel (s->sndchan, true, true);
456 if (s->framedatablocks)
457 hz_bitstream_read_blocks_free(s->framedatablocks);
459 hz_bitstream_read_close(s->bitstream);
463 // utilitarian functions
465 // returns the current error number for the stream, and resets the error
466 // number to DPVSIMPLEDECODEERROR_NONE
467 // if the supplied string pointer variable is not NULL, it will be set to the
469 int dpvsimpledecode_error(void *stream, const char **errorstring)
471 dpvsimpledecodestream_t *s = (dpvsimpledecodestream_t *)stream;
479 case DPVSIMPLEDECODEERROR_NONE:
480 *errorstring = "no error";
482 case DPVSIMPLEDECODEERROR_EOF:
483 *errorstring = "end of file reached (this is not an error)";
485 case DPVSIMPLEDECODEERROR_READERROR:
486 *errorstring = "read error (corrupt or incomplete file)";
488 case DPVSIMPLEDECODEERROR_SOUNDBUFFERTOOSMALL:
489 *errorstring = "sound buffer is too small for decoding frame (please allocate it as large as dpvsimpledecode_getneededsoundbufferlength suggests)";
491 case DPVSIMPLEDECODEERROR_INVALIDRMASK:
492 *errorstring = "invalid red bits mask";
494 case DPVSIMPLEDECODEERROR_INVALIDGMASK:
495 *errorstring = "invalid green bits mask";
497 case DPVSIMPLEDECODEERROR_INVALIDBMASK:
498 *errorstring = "invalid blue bits mask";
500 case DPVSIMPLEDECODEERROR_COLORMASKSOVERLAP:
501 *errorstring = "color bit masks overlap";
503 case DPVSIMPLEDECODEERROR_COLORMASKSEXCEEDBPP:
504 *errorstring = "color masks too big for specified bytes per pixel";
506 case DPVSIMPLEDECODEERROR_UNSUPPORTEDBPP:
507 *errorstring = "unsupported bytes per pixel (must be 2 for 16bit, or 4 for 32bit)";
510 *errorstring = "unknown error";
517 // returns the width of the image data
518 unsigned int dpvsimpledecode_getwidth(void *stream)
520 dpvsimpledecodestream_t *s = (dpvsimpledecodestream_t *)stream;
521 return s->info_imagewidth;
524 // returns the height of the image data
525 unsigned int dpvsimpledecode_getheight(void *stream)
527 dpvsimpledecodestream_t *s = (dpvsimpledecodestream_t *)stream;
528 return s->info_imageheight;
531 // returns the framerate of the stream
532 double dpvsimpledecode_getframerate(void *stream)
534 dpvsimpledecodestream_t *s = (dpvsimpledecodestream_t *)stream;
535 return s->info_framerate;
538 // return aspect ratio of the stream
539 double dpvsimpledecode_getaspectratio(void *stream)
541 dpvsimpledecodestream_t *s = (dpvsimpledecodestream_t *)stream;
542 return s->info_aspectratio;
545 static int dpvsimpledecode_convertpixels(dpvsimpledecodestream_t *s, void *imagedata, int imagebytesperrow)
547 unsigned int a, x, y, width, height;
548 unsigned int Rloss, Rmask, Rshift, Gloss, Gmask, Gshift, Bloss, Bmask, Bshift;
551 width = s->info_imagewidth;
552 height = s->info_imageheight;
554 Rloss = s->info_imageRloss;
555 Rmask = s->info_imageRmask;
556 Rshift = s->info_imageRshift;
557 Gloss = s->info_imageGloss;
558 Gmask = s->info_imageGmask;
559 Gshift = s->info_imageGshift;
560 Bloss = s->info_imageBloss;
561 Bmask = s->info_imageBmask;
562 Bshift = s->info_imageBshift;
565 if (s->info_imagebpp == 4)
567 unsigned int *outrow;
568 for (y = 0;y < height;y++)
570 outrow = (unsigned int *)((unsigned char *)imagedata + y * imagebytesperrow);
571 for (x = 0;x < width;x++)
574 outrow[x] = (((a >> Rloss) & Rmask) << Rshift) | (((a >> Gloss) & Gmask) << Gshift) | (((a >> Bloss) & Bmask) << Bshift);
580 unsigned short *outrow;
581 for (y = 0;y < height;y++)
583 outrow = (unsigned short *)((unsigned char *)imagedata + y * imagebytesperrow);
584 if (Rloss == 19 && Gloss == 10 && Bloss == 3 && Rshift == 11 && Gshift == 5 && Bshift == 0)
587 for (x = 0;x < width;x++)
590 outrow[x] = ((a >> 8) & 0xF800) | ((a >> 5) & 0x07E0) | ((a >> 3) & 0x001F);
595 for (x = 0;x < width;x++)
598 outrow[x] = (((a >> Rloss) & Rmask) << Rshift) | (((a >> Gloss) & Gmask) << Gshift) | (((a >> Bloss) & Bmask) << Bshift);
606 static int dpvsimpledecode_decompressimage(dpvsimpledecodestream_t *s)
608 int i, a, b, colors, g, x1, y1, bw, bh, width, height, palettebits;
609 unsigned int palette[256], *outrow, *out;
611 width = s->info_imagewidth;
612 height = s->info_imageheight;
613 for (y1 = 0;y1 < height;y1 += g)
615 outrow = s->videopixels + y1 * width;
617 if (y1 + bh > height)
619 for (x1 = 0;x1 < width;x1 += g)
625 if (hz_bitstream_read_bit(s->framedatablocks))
628 palettebits = hz_bitstream_read_bits(s->framedatablocks, 3);
629 colors = 1 << palettebits;
630 for (i = 0;i < colors;i++)
631 palette[i] = hz_bitstream_read_bits(s->framedatablocks, 24);
634 for (b = 0;b < bh;b++, out += width)
635 for (a = 0;a < bw;a++)
636 out[a] = palette[hz_bitstream_read_bits(s->framedatablocks, palettebits)];
640 for (b = 0;b < bh;b++, out += width)
641 for (a = 0;a < bw;a++)
650 // decodes a video frame to the supplied output pixels
651 int dpvsimpledecode_video(void *stream, void *imagedata, unsigned int Rmask, unsigned int Gmask, unsigned int Bmask, unsigned int bytesperpixel, int imagebytesperrow)
653 dpvsimpledecodestream_t *s = (dpvsimpledecodestream_t *)stream;
654 unsigned int framedatasize;
656 s->error = DPVSIMPLEDECODEERROR_NONE;
657 if (dpvsimpledecode_setpixelformat(s, Rmask, Gmask, Bmask, bytesperpixel))
660 hz_bitstream_read_blocks_read(s->framedatablocks, s->bitstream, 8);
661 hz_bitstream_read_bytes(s->framedatablocks, t, 4);
662 if (memcmp(t, "VID0", 4))
665 return (s->error = DPVSIMPLEDECODEERROR_EOF);
667 return (s->error = DPVSIMPLEDECODEERROR_READERROR);
669 framedatasize = hz_bitstream_read_int(s->framedatablocks);
670 hz_bitstream_read_blocks_read(s->framedatablocks, s->bitstream, framedatasize);
671 if (dpvsimpledecode_decompressimage(s))
674 dpvsimpledecode_convertpixels(s, imagedata, imagebytesperrow);