github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/image/jxr/jxrlib/jxrtestlib/JXRTestHdr.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  #include <string.h>
    34  
    35  #include <JXRTest.h>
    36  
    37  #pragma pack(push, 1)
    38  #pragma pack(pop)
    39  
    40  //================================================================
    41  // PKImageEncode_HDR
    42  //================================================================
    43  ERR WriteHDRHeader(
    44      PKImageEncode* pIE)
    45  {
    46      ERR err = WMP_errSuccess;
    47      struct WMPStream* pS = pIE->pStream;
    48  
    49      char txtbuff[100];
    50  
    51      strcpy(txtbuff, "#?RADIANCE\nFORMAT=32-bit_rle_rgbe\n\n");
    52      Call(pS->Write(pS, txtbuff, strlen(txtbuff)));
    53  
    54      pIE->offPixel = strlen(txtbuff);
    55  
    56      sprintf(txtbuff, "-Y %d +X %d\n", pIE->uHeight, pIE->uWidth);
    57      Call(pS->Write(pS, txtbuff, strlen(txtbuff)));
    58      pIE->offPixel += strlen(txtbuff);
    59  
    60      pIE->cbPixel = 4;
    61  
    62      pIE->fHeaderDone = !FALSE;
    63  
    64  Cleanup:
    65      return err;
    66  }
    67  
    68  ERR PKImageEncode_WritePixels_HDR(
    69      PKImageEncode* pIE,
    70      U32 cLine,
    71      U8* pbPixel,
    72      U32 cbStride)
    73  {
    74      ERR err = WMP_errSuccess;
    75  
    76      struct WMPStream* pS = pIE->pStream;
    77      size_t cbLineM = 0, cbLineS = 0;
    78      size_t i = 0;
    79  
    80      // header
    81      if (!pIE->fHeaderDone)
    82      {
    83          // WriteHDRHeader() also inits this object
    84          Call(WriteHDRHeader(pIE));
    85      }
    86  
    87      // body
    88      // calculate line size in memory and in stream
    89      cbLineM = pIE->cbPixel * pIE->uWidth;
    90      cbLineS = (cbLineM + 3) / 4 * 4;
    91  
    92      //FailIf(pRect->X < 0 || pID->uWidth <= pRect->X, WMP_errInvalidParameter);
    93      //FailIf(pRect->Y < 0 || pID->uHeight <= pRect->Y, WMP_errInvalidParameter);
    94      //FailIf(pRect->Width < 0 || pID->uWidth < pRect->X + pRect->Width, WMP_errInvalidParameter);
    95      //FailIf(pRect->Height < 0 || pID->uHeight < pRect->Y + pRect->Height, WMP_errInvalidParameter);
    96      FailIf(cbStride < cbLineM, WMP_errInvalidParameter);
    97  
    98      for (i = 0; i <= cLine - 1; i++)
    99      {
   100          size_t offM = cbStride * i;
   101          size_t offS = cbLineS * (pIE->idxCurrentLine + i);
   102  
   103          Call(pS->SetPos(pS, pIE->offPixel + offS));
   104          Call(pS->Write(pS, pbPixel + offM, cbLineM));
   105      }
   106      pIE->idxCurrentLine += cLine;
   107  
   108  Cleanup:
   109      return err;
   110  }
   111  
   112  ERR PKImageEncode_Create_HDR(
   113      PKImageEncode** ppIE)
   114  {
   115      ERR err = WMP_errSuccess;
   116      PKImageEncode* pIE = NULL;
   117  
   118      Call(PKImageEncode_Create(ppIE));
   119  
   120      pIE = *ppIE;
   121      pIE->WritePixels = PKImageEncode_WritePixels_HDR;
   122  
   123  Cleanup:
   124      return err;
   125  }
   126  
   127  
   128  //================================================================
   129  // PKImageDecode_HDR
   130  //================================================================
   131  ERR ParseHDRHeader(
   132      PKTestDecode* pID,
   133      struct WMPStream* pWS)
   134  {
   135      ERR err = WMP_errSuccess;
   136  
   137      char txtbuff[512];
   138      Bool done = FALSE;
   139  
   140      FailIf(NULL == fgets(txtbuff, 12, pWS->state.file.pFile), WMP_errUnsupportedFormat);
   141      FailIf(0 != strcmp(txtbuff, "#?RADIANCE\n"), WMP_errUnsupportedFormat);
   142  
   143      // Read lines to image size
   144      while (!done) {
   145          FailIf(NULL == fgets(txtbuff, 512, pWS->state.file.pFile), WMP_errUnsupportedFormat);
   146  
   147          if (0 == strncmp(txtbuff, "FORMAT", 6)) {
   148              FailIf(0 != strcmp(txtbuff, "FORMAT=32-bit_rle_rgbe\n"), WMP_errUnsupportedFormat);
   149          }
   150          if (0 == strncmp(txtbuff, "-Y", 2)) {
   151              sscanf(txtbuff, "-Y %d +X %d\n", &pID->uHeight, &pID->uWidth);
   152              done = TRUE;
   153          }
   154        }
   155  
   156      Call(pWS->Read(pWS, txtbuff, 3));
   157  
   158      if(((2 == txtbuff[0]) && (2 == txtbuff[1]) && (0 == (txtbuff[2] & 0x80))) ||
   159         ((1 == txtbuff[0]) && (1 == txtbuff[1]) && (1 == txtbuff[2])))
   160      {
   161          printf("Doesn't support compressed HDR files.\n");
   162          err = WMP_errUnsupportedFormat;
   163          goto Cleanup;
   164      }
   165  
   166      // Set header other header parameters
   167      pID->guidPixFormat = GUID_PKPixelFormat32bppRGBE;
   168      pID->EXT.HDR.cbPixel = 4; 
   169      // Set pointer to first pixel
   170      Call(pWS->GetPos(pWS, &pID->EXT.HDR.offPixel));
   171      pID->EXT.HDR.offPixel -= 3;
   172      Call(pWS->SetPos(pWS, pID->EXT.HDR.offPixel));
   173  
   174      // We don't need: pID->fResX and pID->fResY
   175  Cleanup:
   176      return err;
   177  }
   178  
   179  ERR PKImageDecode_Initialize_HDR(
   180      PKTestDecode* pID,
   181      struct WMPStream* pWS)
   182  {
   183      ERR err = WMP_errSuccess;
   184  
   185      Call(PKTestDecode_Initialize(pID, pWS));
   186      Call(ParseHDRHeader(pID, pWS));
   187  
   188  Cleanup:
   189      return err;
   190  }
   191  
   192  ERR PKImageDecode_Copy_HDR(
   193      PKTestDecode* pID,
   194      const PKRect* pRect,
   195      U8* pb,
   196      U32 cbStride)
   197  {
   198      ERR err = WMP_errSuccess;
   199  
   200      struct WMPStream* pS = pID->pStream;
   201  
   202      size_t cbLineS = (pID->EXT.HDR.cbPixel * pID->uWidth + 3) / 4 * 4;
   203      size_t cbLineM = pID->EXT.HDR.cbPixel * pRect->Width;
   204      
   205      I32 i = 0;
   206  
   207      //FailIf(pRect->X < 0 || pID->uWidth <= pRect->X, WMP_errInvalidParameter);
   208      //FailIf(pRect->Y < 0 || pID->uHeight <= pRect->Y, WMP_errInvalidParameter);
   209      //FailIf(pRect->Width < 0 || pID->uWidth < pRect->X + pRect->Width, WMP_errInvalidParameter);
   210      //FailIf(pRect->Height < 0 || pID->uHeight < pRect->Y + pRect->Height, WMP_errInvalidParameter);
   211      FailIf(cbStride < cbLineM, WMP_errInvalidParameter);
   212  
   213      for (i = pRect->Y ; i < pRect->Y + pRect->Height ; i++)
   214      {
   215          size_t offLine = pID->EXT.HDR.cbPixel * pRect->X;
   216          size_t offS = cbLineS * i + offLine;
   217          size_t offM = cbStride * (i - pRect->Y) + offLine;
   218  
   219          Call(pS->SetPos(pS, pID->EXT.HDR.offPixel + offS));
   220          Call(pS->Read(pS, pb + offM, cbLineM));
   221      }
   222  
   223  Cleanup:
   224      return err;
   225  }
   226  
   227  ERR PKImageDecode_Create_HDR(
   228      PKTestDecode** ppID)
   229  {
   230      ERR err = WMP_errSuccess;
   231      PKTestDecode* pID = NULL;
   232  
   233      Call(PKTestDecode_Create(ppID));
   234  
   235      pID = *ppID;
   236      pID->Initialize = PKImageDecode_Initialize_HDR;
   237      pID->Copy = PKImageDecode_Copy_HDR;
   238  
   239  Cleanup:
   240      return err;
   241  }
   242