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