/ source / libsmackerdec / include / SmackerDecoder.h
SmackerDecoder.h
  1  /*
  2   * libsmackerdec - Smacker video decoder
  3   * Copyright (C) 2011 Barry Duncan
  4   *
  5   * This library is free software; you can redistribute it and/or
  6   * modify it under the terms of the GNU Lesser General Public
  7   * License as published by the Free Software Foundation; either
  8   * version 2.1 of the License, or (at your option) any later version.
  9   *
 10   * This library is distributed in the hope that it will be useful,
 11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13   * Lesser General Public License for more details.
 14   *
 15   * You should have received a copy of the GNU Lesser General Public
 16   * License along with this library; if not, write to the Free Software
 17   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 18   */
 19  
 20  /* This code is based on smacker.c from the FFmpeg project which can be obtained from http://www.ffmpeg.org/
 21   * below is the license from smacker.c
 22   * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 23  
 24  /*
 25   * Smacker decoder
 26   * Copyright (c) 2006 Konstantin Shishkov
 27   *
 28   * This file is part of FFmpeg.
 29   *
 30   * FFmpeg is free software; you can redistribute it and/or
 31   * modify it under the terms of the GNU Lesser General Public
 32   * License as published by the Free Software Foundation; either
 33   * version 2.1 of the License, or (at your option) any later version.
 34   *
 35   * FFmpeg is distributed in the hope that it will be useful,
 36   * but WITHOUT ANY WARRANTY; without even the implied warranty of
 37   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 38   * Lesser General Public License for more details.
 39   *
 40   * You should have received a copy of the GNU Lesser General Public
 41   * License along with FFmpeg; if not, write to the Free Software
 42   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 43   */
 44  
 45  #ifndef _SmackerDecoder_h_
 46  #define _SmackerDecoder_h_
 47  
 48  #include <stdint.h>
 49  #include "FileStream.h"
 50  #include "BitReader.h"
 51  #include "collections.h"
 52  
 53  // exportable interface
 54  struct SmackerHandle
 55  {
 56  	bool isValid;
 57  	int instanceIndex;
 58  };
 59  
 60  struct SmackerAudioInfo
 61  {
 62  	uint32_t sampleRate;
 63  	uint8_t  nChannels;
 64  	uint8_t  bitsPerSample;
 65  
 66  	uint32_t idealBufferSize;
 67  };
 68  
 69  SmackerHandle     Smacker_Open                 (const char *fileName);
 70  void              Smacker_Close                (SmackerHandle &handle);
 71  uint32_t          Smacker_GetNumAudioTracks    (SmackerHandle &handle);
 72  SmackerAudioInfo  Smacker_GetAudioTrackDetails (SmackerHandle &handle, uint32_t trackIndex);
 73  uint32_t          Smacker_GetAudioData         (SmackerHandle &handle, uint32_t trackIndex, int16_t *data);
 74  uint32_t          Smacker_GetNumFrames         (SmackerHandle &handle);
 75  void              Smacker_GetFrameSize         (SmackerHandle &handle, uint32_t &width, uint32_t &height);
 76  uint32_t          Smacker_GetCurrentFrameNum   (SmackerHandle &handle);
 77  uint32_t          Smacker_GetNextFrame         (SmackerHandle &handle);
 78  float             Smacker_GetFrameRate         (SmackerHandle &handle);
 79  void              Smacker_GetPalette           (SmackerHandle &handle, uint8_t *palette);
 80  void              Smacker_GetFrame             (SmackerHandle &handle, uint8_t *frame);
 81  void              Smacker_GotoFrame            (SmackerHandle &handle, uint32_t frameNum);
 82  
 83  const int kMaxAudioTracks = 7;
 84  
 85  // forward declare
 86  struct HuffContext;
 87  struct DBCtx;
 88  
 89  struct SmackerAudioTrack
 90  {
 91  	uint32_t sizeInBytes;
 92  	uint32_t flags;
 93  	uint32_t sampleRate;
 94  	uint8_t  nChannels;
 95  	uint8_t  bitsPerSample;
 96  //	int	     compressionType;
 97  
 98  	uint8_t  *buffer;
 99  	uint32_t bufferSize;
100  
101  	uint32_t bytesReadThisFrame;
102  };
103  
104  class SmackerDecoder
105  {
106  	public:
107  		uint32_t frameWidth;
108  		uint32_t frameHeight;
109  
110  		SmackerDecoder();
111  		~SmackerDecoder();
112  
113  		bool Open(const char *fileName);
114  		void GetPalette(uint8_t *palette);
115  		void GetFrame(uint8_t *frame);
116  
117  		SmackerAudioInfo GetAudioTrackDetails(uint32_t trackIndex);
118  		uint32_t GetAudioData(uint32_t trackIndex, int16_t *audioBuffer);
119  		uint32_t GetNumFrames();
120  		uint32_t GetCurrentFrameNum();
121  		float GetFrameRate();
122  		void GetNextFrame();
123  		void GotoFrame(uint32_t frameNum);
124  
125  	private:
126  		SmackerCommon::FileStream file;
127  		char signature[4];
128  
129  		// video related members
130  		uint32_t nFrames;
131  		uint32_t fps; // frames per second
132  
133  		uint8_t palette[768];
134  		uint8_t *picture;
135  
136  		bool isVer4;
137  
138  		SmackerAudioTrack audioTracks[kMaxAudioTracks];
139  
140  		uint32_t treeSize;
141  		uint32_t mMapSize, MClrSize, fullSize, typeSize;
142  
143  		GrowArray<int> mmap_tbl;
144  		GrowArray<int> mclr_tbl;
145  		GrowArray<int> full_tbl;
146  		GrowArray<int> type_tbl;
147  
148  		int mmap_last[3], mclr_last[3], full_last[3], type_last[3];
149  
150  		GrowArray<uint32_t> frameSizes;
151  		GrowArray<uint8_t> frameFlags;
152  
153  		uint32_t currentFrame;
154  		int32_t nextPos;
155          int32_t firstFrameFilePos;
156  
157  		bool DecodeHeaderTrees();
158  		int DecodeHeaderTree(SmackerCommon::BitReader &bits, GrowArray<int> &recodes, int *last, int size);
159  		int DecodeTree(SmackerCommon::BitReader &bits, HuffContext *hc, uint32_t prefix, int length);
160  		int DecodeBigTree(SmackerCommon::BitReader &bits, HuffContext *hc, DBCtx *ctx);
161  		int GetCode(SmackerCommon::BitReader &bits, GrowArray<int> &recode, int *last);
162  		int ReadPacket();
163  		int DecodeFrame(uint32_t frameSize);
164  		void GetFrameSize(uint32_t &width, uint32_t &height);
165  		int DecodeAudio(uint32_t size, SmackerAudioTrack &track);
166  };
167  
168  #endif