github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/image/jxr/jxrlib/jxrtestlib/JXRTestPnm.c (about) 1 //*@@@+++@@@@****************************************************************** 2 // 3 // Copyright Microsoft Corp. 4 // All rights reserved. 5 // 6 // Redistribution and use in source and binary forms, with or without 7 // modification, are permitted provided that the following conditions are met: 8 // 9 // Redistributions of source code must retain the above copyright notice, 10 // this list of conditions and the following disclaimer. 11 // Redistributions in binary form must reproduce the above copyright notice, 12 // this list of conditions and the following disclaimer in the documentation 13 // and/or other materials provided with the distribution. 14 // 15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 // POSSIBILITY OF SUCH DAMAGE. 26 // 27 //*@@@---@@@@****************************************************************** 28 #ifndef ANSI 29 #define _CRT_SECURE_NO_WARNINGS 30 #endif ANSI 31 32 #include <stdlib.h> 33 34 #include <JXRTest.h> 35 36 37 //================================================================ 38 // PKImageEncode_PNM helpers 39 //================================================================ 40 ERR WritePNMHeader(PKImageEncode* pIE) 41 { 42 ERR err = WMP_errSuccess; 43 44 PKPixelInfo PI; 45 struct WMPStream* pS = pIE->pStream; 46 U8 buf[64] = {0}; 47 int cb = 0; 48 49 char szSig[2]; 50 U32 uMaxVal = 0; 51 52 PI.pGUIDPixFmt = &pIE->guidPixFormat; 53 PixelFormatLookup(&PI, LOOKUP_FORWARD); 54 55 if (IsEqualGUID(&GUID_PKPixelFormatBlackWhite, PI.pGUIDPixFmt)) 56 { 57 szSig[0] = 'P', szSig[1] = '5'; 58 uMaxVal = 1; 59 } 60 else if (IsEqualGUID(&GUID_PKPixelFormat8bppGray, PI.pGUIDPixFmt)) 61 { 62 szSig[0] = 'P', szSig[1] = '5'; 63 uMaxVal = 255; 64 } 65 else if (IsEqualGUID(&GUID_PKPixelFormat24bppRGB, PI.pGUIDPixFmt)) 66 { 67 szSig[0] = 'P', szSig[1] = '6'; 68 uMaxVal = 255; 69 } 70 else if (IsEqualGUID(&GUID_PKPixelFormat48bppRGB, PI.pGUIDPixFmt)) 71 { 72 szSig[0] = 'P', szSig[1] = '6'; 73 uMaxVal = 65535; 74 } 75 else if (IsEqualGUID(&GUID_PKPixelFormat16bppGray, PI.pGUIDPixFmt)) 76 { 77 szSig[0] = 'P', szSig[1] = '6'; 78 uMaxVal = 65535; 79 } 80 else if (IsEqualGUID(&GUID_PKPixelFormat96bppRGBFloat, PI.pGUIDPixFmt)) 81 { 82 szSig[0] = 'P', szSig[1] = 'F'; 83 } 84 else 85 Call(WMP_errUnsupportedFormat); 86 87 if('P' == szSig[0] && 'F' == szSig[1]) 88 cb = sprintf((char *) buf, "%c%c\n%u\n%u\n%s\n", 89 szSig[0], szSig[1], (int)pIE->uWidth, (int)pIE->uHeight, "-1.0000"); 90 else 91 cb = sprintf((char *) buf, "%c%c\n%u %u\n%u\n", 92 szSig[0], szSig[1], (int)pIE->uWidth, (int)pIE->uHeight, (int)uMaxVal); 93 94 assert(cb < sizeof2(buf)); 95 Call(pS->Write(pS, buf, cb)); 96 97 Call(pS->GetPos(pS, &pIE->offPixel)); 98 pIE->cbPixel = ((PI.cbitUnit + 7) >> 3);// ->cbPixel / pPI->cbPixelDenom; 99 pIE->fHeaderDone = !FALSE; 100 101 Cleanup: 102 return err; 103 } 104 105 //================================================================ 106 // PKImageEncode_PNM 107 //================================================================ 108 ERR PKImageEncode_WritePixels_PNM( 109 PKImageEncode* pIE, 110 U32 cLine, 111 U8* pbPixel, 112 U32 cbStride) 113 { 114 ERR err = WMP_errSuccess; 115 116 struct WMPStream* pS = pIE->pStream; 117 size_t cbLine = 0; 118 size_t offPos = 0; 119 size_t i = 0; 120 121 // header 122 if (!pIE->fHeaderDone) 123 { 124 Call(WritePNMHeader(pIE)); 125 } 126 127 // body 128 cbLine = pIE->cbPixel * pIE->uWidth; 129 FailIf(cbStride < cbLine, WMP_errInvalidParameter); 130 131 offPos = pIE->offPixel + cbLine * pIE->idxCurrentLine; 132 Call(pS->SetPos(pS, offPos)); 133 134 for (i = 0; i < cLine; ++i) 135 { 136 Call(pS->Write(pS, pbPixel + cbStride * i, cbLine)); 137 } 138 pIE->idxCurrentLine += cLine; 139 140 Cleanup: 141 return err; 142 } 143 144 ERR PKImageEncode_Create_PNM( 145 PKImageEncode** ppIE) 146 { 147 ERR err = WMP_errSuccess; 148 PKImageEncode* pIE = NULL; 149 150 Call(PKImageEncode_Create(ppIE)); 151 152 pIE = *ppIE; 153 pIE->WritePixels = PKImageEncode_WritePixels_PNM; 154 155 Cleanup: 156 return err; 157 } 158 159 160 //================================================================ 161 // PKImageDecode_PNM helpers 162 //================================================================ 163 ERR GetLineSkipPound(struct WMPStream* pWS, U8* pb, size_t cb) 164 { 165 ERR err = WMP_errSuccess; 166 U8 *pb1; 167 size_t cb1; 168 169 do 170 { 171 pb1 = pb; 172 cb1 = cb; 173 174 do { 175 Call(pWS->Read(pWS, pb1, 1)); 176 cb1--; 177 pb1++; 178 } 179 while (cb1 > 0 && pb1[-1] != '\n'); 180 181 //Call(pWS->GetLine(pWS, pb, cb)); 182 } while('#' == pb[0]); 183 184 Cleanup: 185 return err; 186 } 187 188 ERR ParsePNMHeader( 189 PKTestDecode* pID, 190 struct WMPStream* pWS) 191 { 192 ERR err = WMP_errSuccess; 193 194 U8 line[128] = {0}; 195 size_t idxChannel = 0, idxBitDepth = 0; 196 unsigned int width = 0, height = 0, maxval = 0; 197 198 static const PKPixelFormatGUID* pixFormat[2][2] = 199 { 200 {&GUID_PKPixelFormat8bppGray, &GUID_PKPixelFormat16bppGray,}, 201 {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat48bppRGB,}, 202 }; 203 204 //================================ 205 Call(GetLineSkipPound(pWS, line, sizeof2(line))); 206 if (line == (U8 *) strstr((char *) line, "P5")) 207 { 208 idxChannel = 0; 209 Call(GetLineSkipPound(pWS, line, sizeof2(line))); 210 FailIf(2 != sscanf((char *) line, "%u %u", &width, &height), WMP_errUnsupportedFormat); 211 } 212 else if(line == (U8 *) strstr((char *) line, "P6")) 213 { 214 idxChannel = 1; 215 Call(GetLineSkipPound(pWS, line, sizeof2(line))); 216 FailIf(2 != sscanf((char *) line, "%u %u", &width, &height), WMP_errUnsupportedFormat); 217 } 218 else if(line == (U8 *) strstr((char *) line, "PF")) 219 { 220 idxChannel = 2; 221 Call(GetLineSkipPound(pWS, line, sizeof2(line))); 222 FailIf(1 != sscanf((char *) line, "%u", &width), WMP_errUnsupportedFormat); 223 Call(GetLineSkipPound(pWS, line, sizeof2(line))); 224 FailIf(1 != sscanf((char *) line, "%u", &height), WMP_errUnsupportedFormat); 225 } 226 else 227 { 228 Call(WMP_errUnsupportedFormat); 229 } 230 231 //================================ 232 // Call(GetLineSkipPound(pWS, line, sizeof2(line))); 233 // FailIf(2 != sscanf(line, "%u %u", &width, &height), WMP_errUnsupportedFormat); 234 235 FailIf(0 == width || 0 == height, WMP_errUnsupportedFormat); 236 237 pID->uWidth = (U32)width; 238 pID->uHeight = (U32)height; 239 240 //================================ 241 Call(GetLineSkipPound(pWS, line, sizeof2(line))); 242 243 FailIf(1 != sscanf((char *) line, "%u", &maxval), WMP_errUnsupportedFormat); 244 245 if (2==idxChannel) 246 { 247 FailIf(maxval != -1, WMP_errUnsupportedFormat); 248 pID->guidPixFormat = GUID_PKPixelFormat96bppRGBFloat; 249 } 250 else 251 { 252 FailIf(maxval < 1 || 65535 < maxval, WMP_errUnsupportedFormat); 253 idxBitDepth = 255 < maxval; 254 pID->guidPixFormat = *pixFormat[idxChannel][idxBitDepth]; 255 } 256 257 Call(pWS->GetPos(pWS, &pID->EXT.PNM.offPixel)); 258 259 Cleanup: 260 return err; 261 } 262 263 264 //================================================================ 265 // PKImageDecode_PNM 266 //================================================================ 267 ERR PKImageDecode_Initialize_PNM( 268 PKTestDecode* pID, 269 struct WMPStream* pWS) 270 { 271 ERR err = WMP_errSuccess; 272 273 Call(PKTestDecode_Initialize(pID, pWS)); 274 Call(ParsePNMHeader(pID, pWS)); 275 276 Cleanup: 277 return err; 278 } 279 280 281 ERR PKImageDecode_Copy_PNM( 282 PKTestDecode* pID, 283 const PKRect* pRect, 284 U8* pb, 285 U32 cbStride) 286 { 287 ERR err = WMP_errSuccess; 288 289 struct WMPStream* pS = pID->pStream; 290 PKPixelInfo PI; 291 size_t cbLineS = 0; 292 size_t cbLineM = 0; 293 I32 i = 0; 294 295 PI.pGUIDPixFmt = &pID->guidPixFormat; 296 PixelFormatLookup(&PI, LOOKUP_FORWARD); 297 298 cbLineS = (BD_1 == PI.bdBitDepth ? ((PI.cbitUnit * pID->uWidth + 7) >> 3) : (((PI.cbitUnit + 7) >> 3) * pID->uWidth)); 299 cbLineM = (BD_1 == PI.bdBitDepth ? ((PI.cbitUnit * pRect->Width + 7) >> 3) : (((PI.cbitUnit + 7) >> 3) * pRect->Width)); 300 FailIf(cbStride < cbLineM, WMP_errInvalidParameter); 301 302 for (i = 0; i < pRect->Height; ++i) 303 { 304 size_t offLine = (BD_1 == PI.bdBitDepth ? ((PI.cbitUnit * pRect->X + 7) >> 3) : (((PI.cbitUnit + 7) >> 3) * pRect->X)); 305 size_t offS = cbLineS * (pRect->Y + i) + offLine; 306 size_t offM = cbStride * i + offLine; 307 308 Call(pS->SetPos(pS, pID->EXT.PNM.offPixel + offS)); 309 Call(pS->Read(pS, pb + offM, cbLineM)); 310 } 311 312 Cleanup: 313 return err; 314 } 315 316 ERR PKImageDecode_Create_PNM( 317 PKTestDecode** ppID) 318 { 319 ERR err = WMP_errSuccess; 320 PKTestDecode* pID = NULL; 321 322 Call(PKTestDecode_Create(ppID)); 323 324 pID = *ppID; 325 pID->Initialize = PKImageDecode_Initialize_PNM; 326 pID->Copy = PKImageDecode_Copy_PNM; 327 328 Cleanup: 329 return err; 330 } 331