// ###################################################################### unsigned int getFrameSize(const VideoFormat vidformat, const Dims& imgdims) { const unsigned int sz = imgdims.sz(); unsigned int numer=0, denom=0; getBytesPerPixelForMode(vidformat, &numer, &denom); ASSERT(numer > 0); ASSERT(denom > 0); return (sz * numer) / denom; }
// ###################################################################### GenericFrame MgzJDecoder::readFrame() { // Grab the journal entry for this frame and allocate an appropriate GenericFrame MgzJEncoder::journalEntry entry = itsJournal.at(itsFrameNum); const Dims dims(entry.width, entry.height); const GenericFrame::NativeType pix_type = GenericFrame::NativeType(entry.pix_type); const int num_pix = dims.sz(); GenericFrame frame; //Read in the compressed image to a buffer uint64 comp_image_buf_size = entry.end_byte - entry.start_byte; byte * comp_image_buf = new byte[comp_image_buf_size]; itsFile.seekg(entry.start_byte, std::ios::beg); itsFile.read((char*)comp_image_buf, comp_image_buf_size); //Prepare zlib to do the decompression z_stream strm; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = 0; strm.next_in = Z_NULL; int ret = inflateInit(&strm); if(ret != Z_OK) LFATAL("Could not initialize zlib!"); strm.avail_in = comp_image_buf_size; strm.next_in = comp_image_buf; switch(pix_type) { case GenericFrame::GRAY_U8: { Image<byte> img(dims, NO_INIT); strm.avail_out = num_pix * sizeof(byte); strm.next_out = (unsigned char*)img.getArrayPtr(); ret = inflate(&strm, Z_FINISH); if(ret != Z_STREAM_END) { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); } frame = GenericFrame(img); break; } case GenericFrame::GRAY_U16: { Image<uint16> img(dims, NO_INIT); strm.avail_out = num_pix * sizeof(uint16); strm.next_out = (unsigned char*)img.getArrayPtr(); ret = inflate(&strm, Z_FINISH); if(ret != Z_STREAM_END) { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); } frame = GenericFrame(img); break; } case GenericFrame::GRAY_F32: { Image<float> img(dims, NO_INIT); strm.avail_out = num_pix * sizeof(float); strm.next_out = (unsigned char*)img.getArrayPtr(); ret = inflate(&strm, Z_FINISH); if(ret != Z_STREAM_END) { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); } frame = GenericFrame(img, entry.flags); break; } case GenericFrame::RGB_U8: { Image<PixRGB<byte> > img(dims, NO_INIT); strm.avail_out = num_pix * sizeof(PixRGB<byte>); strm.next_out = (unsigned char*)img.getArrayPtr(); ret = inflate(&strm, Z_FINISH); if(ret != Z_STREAM_END) { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); } frame = GenericFrame(img); break; } case GenericFrame::RGB_U16: { Image<PixRGB<uint16> > img(dims, NO_INIT); strm.avail_out = num_pix * sizeof(PixRGB<uint16>); strm.next_out = (unsigned char*)img.getArrayPtr(); ret = inflate(&strm, Z_FINISH); if(ret != Z_STREAM_END) { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); } frame = GenericFrame(img); break; } case GenericFrame::RGB_F32: { Image<PixRGB<float> > img(dims, NO_INIT); strm.avail_out = num_pix * sizeof(PixRGB<float>); strm.next_out = (unsigned char*)img.getArrayPtr(); ret = inflate(&strm, Z_FINISH); if(ret != Z_STREAM_END) { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); } frame = GenericFrame(img, entry.flags); break; } case GenericFrame::VIDEO: { const size_t vidSize = getFrameSize(VideoFormat(entry.flags), dims); ArrayHandle<byte> vidBuffer(new ArrayData<byte>(Dims(vidSize,1), NO_INIT)); strm.avail_out = vidSize; strm.next_out = (unsigned char*)vidBuffer.uniq().dataw(); ret = inflate(&strm, Z_FINISH); if(ret != Z_STREAM_END) { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); } frame = GenericFrame(VideoFrame(vidBuffer, dims, VideoFormat(entry.flags), bool(entry.byte_swap))); break; } default: LFATAL("Could Not Open Frame Of Type: %d!", pix_type); } inflateEnd(&strm); delete [] comp_image_buf; return frame; }