32 #ifndef SPL_pnmCodec_hpp
33 #define SPL_pnmCodec_hpp
39 #include <SPL/config.hpp>
58 pnmMagicTxtPbm = 0x5031,
59 pnmMagicTxtPgm = 0x5032,
60 pnmMagicTxtPpm = 0x5033,
61 pnmMagicBinPbm = 0x5034,
62 pnmMagicBinPgm = 0x5035,
63 pnmMagicBinPpm = 0x5036,
83 const int pnmMaxLineLen = 80;
107 PnmType pnmGetType(PnmMagic magic);
112 PnmFmt pnmGetFmt(PnmMagic magic);
117 int pnmMaxValToPrec(
int maxVal);
122 int pnmGetNumComps(PnmType type);
128 inline long pnmOnes(
int n)
130 return (1UL << n) - 1;
140 int pnmGetHeader(std::istream& in, PnmHeader& header);
145 int pnmPutHeader(std::ostream& out, PnmHeader& header);
150 int pnmGetChar(std::istream& in);
155 int pnmGetTxtBit(std::istream& in);
160 long pnmGetTxtInt(std::istream& in,
bool sgnd,
int& status);
165 long pnmGetBinInt(std::istream& in,
int wordSize,
bool sgnd,
int& status);
170 int pnmPutBinInt(std::ostream& out,
int wordSize,
bool sgnd,
long val);
179 template <
class GetData>
180 int pnmEncode(std::ostream& outStream,
int width,
int height,
int numComps,
181 int maxVal,
bool sgnd, GetData& getData,
bool binaryFormat)
186 header.magic = binaryFormat ? pnmMagicBinPbm : pnmMagicTxtPbm;
188 header.magic = binaryFormat ? pnmMagicBinPgm : pnmMagicTxtPgm;
190 }
else if (numComps == 3) {
191 header.magic = binaryFormat ? pnmMagicBinPpm : pnmMagicTxtPpm;
195 header.width = width;
196 header.height = height;
197 header.maxVal = maxVal;
200 if (pnmPutHeader(outStream, header)) {
203 if (putData(outStream, header, getData)) {
212 template <
class GetData>
213 int putData(std::ostream& out, PnmHeader& header, GetData& getData)
215 int prec = pnmMaxValToPrec(header.maxVal);
216 int fmt = pnmGetFmt(header.magic);
217 PnmType type = pnmGetType(header.magic);
218 int numComps = pnmGetNumComps(type);
221 for (
int y = header.height - 1; y >= 0; --y) {
222 if (fmt == pnmFmtBin) {
223 if (type == pnmTypePbm) {
226 for (
int x = 0; x < header.width; ++x) {
228 val = (val << 1) | (b & 1);
231 if (!out.put(static_cast<unsigned char>(val))) {
239 assert(numBits <= 8);
241 if (!out.put(static_cast<unsigned char>(val))) {
246 for (
int x = 0; x < header.width; ++x) {
247 for (
int c = 0; c < numComps; ++c) {
249 long val = getData();
250 if (pnmPutBinInt(out, prec, header.sgnd, val)) {
257 for (
int x = 0; x < header.width; ++x) {
258 for (
int c = 0; c < numComps; ++c) {
260 long val = getData();
261 std::ostringstream buf;
263 int n = buf.str().length();
264 if (lineLen && lineLen + n + 2 > pnmMaxLineLen) {
268 if (lineLen && prec > 1) {
277 if (fmt == pnmFmtTxt && lineLen) {
293 template <
class Initialize>
294 int pnmDecode(std::istream& inStream, Initialize& initialize)
297 if (pnmGetHeader(inStream, header)) {
300 #if defined(PNM_DEBUG)
302 <<
"magic " << std::hex << header.magic <<
" "
303 << std::dec <<
" width " << header.width <<
" "
304 <<
"height " << header.height <<
" "
305 <<
"maxVal " << header.maxVal <<
"\n"
308 int numComps = pnmGetNumComps(pnmGetType(header.magic));
309 typename Initialize::PutData putData;
310 initialize(header.width, header.height, numComps, header.maxVal, header.sgnd, putData);
311 if (getData(inStream, header, putData)) {
320 template <
class PutData>
321 int getData(std::istream& in, PnmHeader& header, PutData& putData)
323 PnmType type = pnmGetType(header.magic);
324 PnmFmt fmt = pnmGetFmt(header.magic);
325 int numComps = pnmGetNumComps(type);
326 int prec = pnmMaxValToPrec(header.maxVal);
327 for (
int y = header.height - 1; y >= 0; --y) {
328 if (type == pnmTypePbm) {
329 if (fmt == pnmFmtBin) {
330 for (
int x = 0; x < header.width;) {
332 if ((c = in.get()) == std::char_traits<char>::eof()) {
336 while (n > 0 && x < header.width) {
338 putData((c >> 7) & 1);
345 for (
int x = 0; x < header.width; ++x) {
347 if ((val = pnmGetTxtBit(in)) < 0) {
355 if (fmt == pnmFmtBin) {
356 for (
int x = 0; x < header.width; ++x) {
357 for (
int c = 0; c < numComps; ++c) {
360 if (val = pnmGetBinInt(in, prec, header.sgnd, status),
369 for (
int x = 0; x < header.width; ++x) {
370 for (
int c = 0; c < numComps; ++c) {
373 if (val = pnmGetTxtInt(in, header.sgnd, status), status) {
Definition: Arcball.hpp:48