00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "Media/MgzJDecoder.H"
00036 #include <sys/errno.h>
00037
00038
00039 MgzJDecoder::MgzJDecoder(const std::string& fname)
00040 :
00041 itsFileName(fname)
00042 {
00043 init();
00044 }
00045
00046
00047 MgzJDecoder::~MgzJDecoder()
00048 {
00049 shutdown();
00050 }
00051
00052
00053
00054 void MgzJDecoder::init()
00055 {
00056 LDEBUG("Opening File: %s", itsFileName.c_str());
00057
00058
00059
00060 itsFile.open(itsFileName.c_str(), std::ios::in|std::ios::binary|std::ios::ate);
00061
00062 if(!itsFile.is_open())
00063 LFATAL("Could not open file: %s", itsFileName.c_str());
00064
00065
00066 std::ifstream::pos_type fsize = itsFile.tellg();
00067
00068
00069 uint64 journal_start;
00070 itsFile.seekg(-8, std::ios::end);
00071 itsFile.read((char*)&journal_start, 8);
00072
00073
00074 byte meta_meta_buffer[16];
00075 itsFile.seekg(journal_start, std::ios::beg);
00076 itsFile.read((char*)meta_meta_buffer, 16);
00077
00078
00079 uint64 num_entries;
00080 memcpy((char*)&num_entries, meta_meta_buffer, 8);
00081
00082
00083
00084 uint64 flags;
00085 memcpy((char*)&flags, meta_meta_buffer+8, 8);
00086 ASSERT(flags == 0);
00087
00088
00089 uint64 journal_data_start = journal_start + 16;
00090
00091
00092 uint64 journal_buf_size = (uint64)fsize - journal_data_start - 8;
00093 byte journal[journal_buf_size];
00094 itsFile.seekg(journal_data_start, std::ios::beg);
00095 itsFile.read((char*)journal, journal_buf_size);
00096
00097
00098 uint64 entry_size = journal_buf_size / num_entries;
00099
00100
00101 itsJournal.clear();
00102 for(uint64 buf_pos=0; buf_pos < journal_buf_size; buf_pos += entry_size)
00103 {
00104 MgzJEncoder::journalEntry entry;
00105 memcpy((char*)&entry, journal+buf_pos, sizeof(MgzJEncoder::journalEntry));
00106 itsJournal.push_back(entry);
00107 }
00108
00109 }
00110
00111 void MgzJDecoder::shutdown()
00112 {
00113 if(itsFile.is_open())
00114 itsFile.close();
00115 }
00116
00117
00118 GenericFrame MgzJDecoder::readFrame()
00119 {
00120
00121
00122
00123 MgzJEncoder::journalEntry entry = itsJournal.at(itsFrameNum);
00124 const Dims dims(entry.width, entry.height);
00125 const GenericFrame::NativeType pix_type = GenericFrame::NativeType(entry.pix_type);
00126 const int num_pix = dims.sz();
00127 GenericFrame frame;
00128
00129
00130 uint64 comp_image_buf_size = entry.end_byte - entry.start_byte;
00131 byte comp_image_buf[comp_image_buf_size];
00132 itsFile.seekg(entry.start_byte, std::ios::beg);
00133 itsFile.read((char*)comp_image_buf, comp_image_buf_size);
00134
00135
00136 z_stream strm;
00137 strm.zalloc = Z_NULL;
00138 strm.zfree = Z_NULL;
00139 strm.opaque = Z_NULL;
00140 strm.avail_in = 0;
00141 strm.next_in = Z_NULL;
00142 int ret = inflateInit(&strm);
00143 if(ret != Z_OK)
00144 LFATAL("Could not initialize zlib!");
00145
00146 strm.avail_in = comp_image_buf_size;
00147 strm.next_in = comp_image_buf;
00148 switch(pix_type)
00149 {
00150 case GenericFrame::GRAY_U8:
00151 {
00152 Image<byte> img(dims, NO_INIT);
00153 strm.avail_out = num_pix * sizeof(byte);
00154 strm.next_out = (unsigned char*)img.getArrayPtr();
00155 ret = inflate(&strm, Z_FINISH);
00156 if(ret != Z_STREAM_END)
00157 { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); }
00158 frame = GenericFrame(img);
00159
00160 break;
00161 }
00162 case GenericFrame::GRAY_U16:
00163 {
00164 Image<uint16> img(dims, NO_INIT);
00165 strm.avail_out = num_pix * sizeof(uint16);
00166 strm.next_out = (unsigned char*)img.getArrayPtr();
00167 ret = inflate(&strm, Z_FINISH);
00168 if(ret != Z_STREAM_END)
00169 { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); }
00170 frame = GenericFrame(img);
00171
00172 break;
00173 }
00174 case GenericFrame::GRAY_F32:
00175 {
00176 Image<float> img(dims, NO_INIT);
00177 strm.avail_out = num_pix * sizeof(float);
00178 strm.next_out = (unsigned char*)img.getArrayPtr();
00179 ret = inflate(&strm, Z_FINISH);
00180 if(ret != Z_STREAM_END)
00181 { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); }
00182 frame = GenericFrame(img, entry.flags);
00183
00184 break;
00185 }
00186 case GenericFrame::RGB_U8:
00187 {
00188 Image<PixRGB<byte> > img(dims, NO_INIT);
00189 strm.avail_out = num_pix * sizeof(PixRGB<byte>);
00190 strm.next_out = (unsigned char*)img.getArrayPtr();
00191 ret = inflate(&strm, Z_FINISH);
00192 if(ret != Z_STREAM_END)
00193 { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); }
00194 frame = GenericFrame(img);
00195
00196 break;
00197 }
00198 case GenericFrame::RGB_U16:
00199 {
00200 Image<PixRGB<uint16> > img(dims, NO_INIT);
00201 strm.avail_out = num_pix * sizeof(PixRGB<uint16>);
00202 strm.next_out = (unsigned char*)img.getArrayPtr();
00203 ret = inflate(&strm, Z_FINISH);
00204 if(ret != Z_STREAM_END)
00205 { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); }
00206 frame = GenericFrame(img);
00207
00208 break;
00209 }
00210 case GenericFrame::RGB_F32:
00211 {
00212 Image<PixRGB<float> > img(dims, NO_INIT);
00213 strm.avail_out = num_pix * sizeof(PixRGB<float>);
00214 strm.next_out = (unsigned char*)img.getArrayPtr();
00215 ret = inflate(&strm, Z_FINISH);
00216 if(ret != Z_STREAM_END)
00217 { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); }
00218 frame = GenericFrame(img, entry.flags);
00219
00220 break;
00221 }
00222 case GenericFrame::VIDEO:
00223 {
00224 const size_t vidSize = getFrameSize(VideoFormat(entry.flags), dims);
00225 ArrayHandle<byte> vidBuffer(new ArrayData<byte>(Dims(vidSize,1), NO_INIT));
00226 strm.avail_out = vidSize;
00227 strm.next_out = (unsigned char*)vidBuffer.uniq().dataw();
00228 ret = inflate(&strm, Z_FINISH);
00229 if(ret != Z_STREAM_END)
00230 { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); }
00231 frame = GenericFrame(VideoFrame(vidBuffer, dims, VideoFormat(entry.flags), bool(entry.byte_swap)));
00232 break;
00233 }
00234 default:
00235 LFATAL("Could Not Open Frame Of Type: %d!", pix_type);
00236 }
00237
00238 inflateEnd(&strm);
00239 return frame;
00240 }
00241
00242
00243 int MgzJDecoder::getNumFrames()
00244 {
00245 return itsJournal.size();
00246 }
00247
00248
00249 bool MgzJDecoder::setFrameNumber(unsigned int n)
00250 {
00251 if(n < itsJournal.size())
00252 {
00253 itsFrameNum = n;
00254 return true;
00255 }
00256 LINFO("Could not set frame number to %d (only %lu frames available)", n, (unsigned long)itsJournal.size());
00257 return false;
00258 }
00259
00260
00261