MgzJEncoder.C
Go to the documentation of this file.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/MgzJEncoder.H"
00036
00037 #include "Image/Image.H"
00038 #include "Image/Pixels.H"
00039 #include "Util/log.H"
00040 #include "Util/sformat.H"
00041 #include "rutz/trace.h"
00042
00043 #include <zlib.h>
00044 #include <sstream>
00045
00046
00047 MgzJEncoder::MgzJEncoder(const std::string& fname, const int complev)
00048 {
00049 LINFO("Opening File: %s", fname.c_str());
00050 itsFile.open(fname.c_str(), std::ios::out | std::ios::binary);
00051 itsComplev = complev;
00052 }
00053
00054
00055 MgzJEncoder::~MgzJEncoder()
00056 {
00057 this->close();
00058 }
00059
00060
00061 int MgzJEncoder::close()
00062 {
00063 if(itsFile.is_open())
00064 {
00065 LINFO("Please wait... Writing %lu entries to the file journal", (unsigned long)itsJournal.size());
00066
00067 uint64 journal_position = itsFile.tellp();
00068
00069
00070
00071
00072
00073
00074 size_t journal_size = 8 + 8 + itsJournal.size() * sizeof(MgzJEncoder::journalEntry) + 8;
00075 byte journal[journal_size];
00076
00077
00078 uint64 num_entries = itsJournal.size();
00079 memcpy(journal, (char*)&num_entries, 8);
00080
00081
00082
00083
00084 uint64 flags = 0;
00085 memcpy(journal+8, (char*)&flags, 8);
00086
00087
00088
00089
00090 for(size_t jIdx=0; jIdx<itsJournal.size(); jIdx++)
00091 {
00092
00093
00094 size_t jPos = 16+jIdx*sizeof(MgzJEncoder::journalEntry);
00095
00096
00097 memcpy(journal+jPos, (char *)&itsJournal[jIdx], sizeof(MgzJEncoder::journalEntry));
00098 }
00099
00100
00101 memcpy(journal + 8 + 8 + itsJournal.size() * sizeof(MgzJEncoder::journalEntry), &journal_position, 8);
00102
00103
00104 itsFile.write((char*)journal, journal_size);
00105
00106 itsFile.close();
00107 }
00108 return 1;
00109 }
00110
00111
00112 void MgzJEncoder::writeFrame(const GenericFrame& frame)
00113 {
00114
00115 MgzJEncoder::journalEntry entry;
00116 entry.pix_type = frame.nativeType();
00117 entry.width = frame.getWidth();
00118 entry.height = frame.getHeight();
00119
00120
00121 if(frame.nativeType() == GenericFrame::VIDEO)
00122 {
00123 entry.flags = frame.asVideo().getMode();
00124 entry.byte_swap = frame.asVideo().getByteSwap();
00125 }
00126 else
00127 {
00128 entry.flags = frame.floatFlags();
00129 }
00130
00131 int num_pix = frame.getWidth() * frame.getHeight();
00132 size_t num_bytes = -1;
00133 unsigned char* frameBase = NULL;
00134 switch(frame.nativeType())
00135 {
00136 case GenericFrame::GRAY_U8:
00137 num_bytes = sizeof(byte) * num_pix;
00138 frameBase = (unsigned char*)frame.asGrayU8().getArrayPtr();
00139 break;
00140 case GenericFrame::GRAY_U16:
00141 num_bytes = sizeof(uint16) * num_pix;
00142 frameBase = (unsigned char*)frame.asGrayU16().getArrayPtr();
00143 break;
00144 case GenericFrame::GRAY_F32:
00145 num_bytes = sizeof(float) * num_pix;
00146 frameBase = (unsigned char*)frame.asGrayF32().getArrayPtr();
00147 break;
00148 case GenericFrame::RGB_U8:
00149 num_bytes = sizeof(PixRGB<byte>) * num_pix;
00150 frameBase = (unsigned char*)frame.asRgbU8().getArrayPtr();
00151 break;
00152 case GenericFrame::RGB_U16:
00153 num_bytes = sizeof(PixRGB<uint16>) * num_pix;
00154 frameBase = (unsigned char*)frame.asRgbU16().getArrayPtr();
00155 break;
00156 case GenericFrame::RGB_F32:
00157 num_bytes = sizeof(PixRGB<float>) * num_pix;
00158 frameBase = (unsigned char*)frame.asRgbF32().getArrayPtr();
00159 break;
00160 case GenericFrame::VIDEO:
00161 num_bytes = frame.asVideo().getBufSize();
00162 frameBase = (unsigned char*)frame.asVideo().getBuffer();
00163 break;
00164 case GenericFrame::NONE:
00165
00166 break;
00167 default:
00168 LFATAL("Cannot write frames of type %s", frame.nativeTypeName().c_str());
00169 }
00170
00171
00172
00173 size_t outputBufferSize = num_bytes + 1000;
00174 unsigned char outputBuffer[outputBufferSize];
00175
00176
00177 z_stream strm;
00178 strm.zalloc = Z_NULL;
00179 strm.zfree = Z_NULL;
00180 strm.opaque = Z_NULL;
00181
00182 int msg = deflateInit(&strm, itsComplev);
00183 if(msg != Z_OK)
00184 {
00185 std::stringstream reason;
00186 reason << "Could not initialize mgzj encoder (";
00187 switch(msg)
00188 {
00189 case Z_MEM_ERROR:
00190 reason << "Z_MEM_ERROR: Insufficient Memory";
00191 break;
00192 case Z_STREAM_ERROR:
00193 reason << "Z_STREAM_ERROR: Likely an invalid compression level (You chose" << itsComplev << ")";
00194 break;
00195 case Z_VERSION_ERROR:
00196 reason << "Z_VERSION_ERROR: You're using an incompatible version of zlib.h";
00197 break;
00198 default:
00199 reason << "Unknown Error!";
00200 break;
00201 }
00202 reason << ")";
00203 LFATAL("%s", reason.str().c_str());
00204 }
00205
00206
00207 strm.avail_in = num_bytes;
00208 strm.next_in = frameBase;
00209 strm.avail_out = outputBufferSize;
00210 strm.next_out = outputBuffer;
00211
00212
00213 msg = deflate(&strm, Z_FINISH);
00214 (void)deflateEnd(&strm);
00215 if(msg != Z_STREAM_END)
00216 {
00217 std::stringstream reason;
00218 reason << "Failure to deflate (";
00219 switch(msg)
00220 {
00221 case Z_OK:
00222 reason << "Z_OK";
00223 break;
00224 case Z_STREAM_ERROR:
00225 reason << "Z_STREAM_ERROR";
00226 break;
00227 case Z_BUF_ERROR:
00228 reason << "Z_BUF_ERROR";
00229 break;
00230 default:
00231 reason << "Unknown Error!";
00232 break;
00233 }
00234 reason << ")";
00235 LFATAL("%s", reason.str().c_str());
00236 }
00237 size_t compressedSize = outputBufferSize - strm.avail_out;
00238
00239
00240
00241 entry.start_byte = itsFile.tellp();
00242 entry.end_byte = entry.start_byte + compressedSize;
00243 itsJournal.push_back(entry);
00244
00245
00246 itsFile.write((const char*)outputBuffer, compressedSize);
00247 }
00248
00249
00250