func: static int pxr24_uncompress(EXRContext *s, const uint8_t *src,
  
                              int compressed_size, int uncompressed_size,
  
                              EXRThreadData *td)
  
  {
  
      unsigned long dest_len, expected_len = 0;
  
      const uint8_t *in = td->tmp;
  
      uint8_t *out;
  
      int c, i, j;
  
  
  
      for (i = 0; i < s->nb_channels; i++) {
  
          if (s->channels[i].pixel_type == EXR_FLOAT) {
  
              expected_len += (td->xsize * td->ysize * 3);/* PRX 24 store float in 24 bit instead of 32 */
  
          } else if (s->channels[i].pixel_type == EXR_HALF) {
  
              expected_len += (td->xsize * td->ysize * 2);
  
          } else {//UINT 32
  
              expected_len += (td->xsize * td->ysize * 4);
  
          }
  
      }
  
  
  
      dest_len = expected_len;
  
  
  
      if (uncompress(td->tmp, &dest_len, src, compressed_size) != Z_OK) {
  
          return AVERROR_INVALIDDATA;
  
      } else if (dest_len != expected_len) {
  
          return AVERROR_INVALIDDATA;
  
      }
  
  
  
      out = td->uncompressed_data;
  
      for (i = 0; i < td->ysize; i++)
  
          for (c = 0; c < s->nb_channels; c++) {
  
              EXRChannel *channel = &s->channels[c];
  
              const uint8_t *ptr[4];
  
              uint32_t pixel = 0;
  
  
  
              switch (channel->pixel_type) {
  
              case EXR_FLOAT:
  
                  ptr[0] = in;
  
                  ptr[1] = ptr[0] + td->xsize;
  
                  ptr[2] = ptr[1] + td->xsize;
  
                  in     = ptr[2] + td->xsize;
  
  
  
                  for (j = 0; j < td->xsize; ++j) {
  
                      uint32_t diff = (*(ptr[0]++) << 24) |
  
                                      (*(ptr[1]++) << 16) |
  
                                      (*(ptr[2]++) << 8);
  
                      pixel += diff;
  
                      bytestream_put_le32(&out, pixel);
  
                  }
  
                  break;
  
              case EXR_HALF:
  
                  ptr[0] = in;
  
                  ptr[1] = ptr[0] + td->xsize;
  
                  in     = ptr[1] + td->xsize;
  
                  for (j = 0; j < td->xsize; j++) {
  
                      uint32_t diff = (*(ptr[0]++) << 8) | *(ptr[1]++);
  
  
  
                      pixel += diff;
  
                      bytestream_put_le16(&out, pixel);
  
                  }
  
                  break;
  
              case EXR_UINT:
  
                  ptr[0] = in;
  
                  ptr[1] = ptr[0] + s->xdelta;
  
                  ptr[2] = ptr[1] + s->xdelta;
  
                  ptr[3] = ptr[2] + s->xdelta;
  
                  in     = ptr[3] + s->xdelta;
  
  
  
                  for (j = 0; j < s->xdelta; ++j) {
  
                      uint32_t diff = (*(ptr[0]++) << 24) |
  
                      (*(ptr[1]++) << 16) |
  
                      (*(ptr[2]++) << 8 ) |
  
                      (*(ptr[3]++));
  
                      pixel += diff;
  
                      bytestream_put_le32(&out, pixel);
  
                  }
  
                  break;
  
              default:
  
                  return AVERROR_INVALIDDATA;
  
              }
  
          }
  
  
  
      return 0;
  
  }
  