Go to the documentation of this file.00001 #include <imagezero/portableimage.h>
00002
00003 namespace IZ
00004 {
00005 static unsigned char* writeValue(unsigned char* p, unsigned char whiteSpace, int value)
00006 {
00007 unsigned int v = value;
00008 *p++ = whiteSpace;
00009 bool first = true;
00010 unsigned int k = 10000;
00011 while (k > 0)
00012 {
00013 if (v >= k || !first)
00014 {
00015 *p++ = '0' + v / k;
00016 v %= k;
00017 first = false;
00018 }
00019 k /= 10;
00020 }
00021 return p;
00022 }
00023
00024 static const unsigned char* readValue(const unsigned char* p, int& value)
00025 {
00026
00027 unsigned char c;
00028 while (c = *p, true)
00029 {
00030 if (c == ' ' || (c >= '\011' && c <= '\015'))
00031 {
00032 ++p;
00033 }
00034 else if (c == '#')
00035 {
00036 do
00037 {
00038 ++p;
00039 } while (*p != '\n');
00040 }
00041 else
00042 {
00043 break;
00044 }
00045 }
00046 int v = 0;
00047 unsigned int d;
00048 while (d = *p - '0', d < 10U)
00049 {
00050 ++p;
00051 v = 10 * v + d;
00052 }
00053 value = v;
00054 return p;
00055 }
00056
00057 unsigned char* PortableImage::writeHeader(unsigned char* p)
00058 {
00059 *p++ = 'P';
00060
00061 switch (m_components)
00062 {
00063 case 3:
00064 *p++ = '6';
00065 break;
00066 case 1:
00067 *p++ = '5';
00068 break;
00069 default:
00070 return p;
00071 }
00072
00073 p = writeValue(p, '\n', m_width);
00074 p = writeValue(p, ' ', m_height);
00075 p = writeValue(p, '\n', 255);
00076
00077 setSamplesPerLine(m_components * m_width);
00078
00079 *p++ = '\n';
00080 m_data = p;
00081 return p;
00082 }
00083
00084 bool PortableImage::readHeader(const unsigned char* p)
00085 {
00086 if (*p++ != 'P')
00087 {
00088 return false;
00089 }
00090
00091 switch (*p++)
00092 {
00093 case '6':
00094 m_components = 3;
00095 break;
00096 case '5':
00097 m_components = 1;
00098 break;
00099 default:
00100 return false;
00101 }
00102
00103 p = readValue(p, m_width);
00104 p = readValue(p, m_height);
00105 p = readValue(p, m_maxVal);
00106
00107 if (m_maxVal != 255 || m_width < 1 || m_height < 1)
00108 {
00109 return false;
00110 }
00111
00112 setSamplesPerLine(m_components * m_width);
00113
00114 ++p;
00115 m_data = (unsigned char*) p;
00116 return true;
00117 }
00118
00119 PortableImage::PortableImage()
00120 : m_components(0)
00121 {
00122 }
00123
00124 PortableImage::~PortableImage()
00125 {
00126 }
00127 }