15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2011 Google Inc. All Rights Reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license
4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// that can be found in the COPYING file in the root of the source
5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// tree. An additional intellectual property rights grant can be found
6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// in the file PATENTS. All contributing project authors may
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// be found in the AUTHORS file in the root of the source tree.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -----------------------------------------------------------------------------
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Alpha-plane decompression.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: Skal (pascal.massimino@gmail.com)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "./alphai.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "./vp8i.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "./vp8li.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "../utils/quant_levels_dec.h"
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "../utils/utils.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "../webp/format_constants.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//------------------------------------------------------------------------------
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// ALPHDecoder object.
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ALPHDecoder* ALPHNew(void) {
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ALPHDecoder* const dec = (ALPHDecoder*)WebPSafeCalloc(1ULL, sizeof(*dec));
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return dec;
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ALPHDelete(ALPHDecoder* const dec) {
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (dec != NULL) {
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    VP8LDelete(dec->vp8l_dec_);
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    dec->vp8l_dec_ = NULL;
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    WebPSafeFree(dec);
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Decoding.
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Initialize alpha decoding by parsing the alpha header and decoding the image
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// header for alpha data stored using lossless compression.
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Returns false in case of error in alpha header (data too short, invalid
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// compression method or filter, error in lossless header data etc).
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static int ALPHInit(ALPHDecoder* const dec, const uint8_t* data,
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    size_t data_size, int width, int height, uint8_t* output) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ok = 0;
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const uint8_t* const alpha_data = data + ALPHA_HEADER_LEN;
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const size_t alpha_data_size = data_size - ALPHA_HEADER_LEN;
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int rsrv;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  assert(width > 0 && height > 0);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(data != NULL && output != NULL);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  dec->width_ = width;
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  dec->height_ = height;
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (data_size <= ALPHA_HEADER_LEN) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  dec->method_ = (data[0] >> 0) & 0x03;
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  dec->filter_ = (data[0] >> 2) & 0x03;
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  dec->pre_processing_ = (data[0] >> 4) & 0x03;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rsrv = (data[0] >> 6) & 0x03;
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (dec->method_ < ALPHA_NO_COMPRESSION ||
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      dec->method_ > ALPHA_LOSSLESS_COMPRESSION ||
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      dec->filter_ >= WEBP_FILTER_LAST ||
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      dec->pre_processing_ > ALPHA_PREPROCESSED_LEVELS ||
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rsrv != 0) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (dec->method_ == ALPHA_NO_COMPRESSION) {
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const size_t alpha_decoded_size = dec->width_ * dec->height_;
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ok = (alpha_data_size >= alpha_decoded_size);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    assert(dec->method_ == ALPHA_LOSSLESS_COMPRESSION);
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ok = VP8LDecodeAlphaHeader(dec, alpha_data, alpha_data_size, output);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return ok;
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Decodes, unfilters and dequantizes *at least* 'num_rows' rows of alpha
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// starting from row number 'row'. It assumes that rows up to (row - 1) have
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// already been decoded.
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Returns false in case of bitstream error.
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static int ALPHDecode(VP8Decoder* const dec, int row, int num_rows) {
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ALPHDecoder* const alph_dec = dec->alph_dec_;
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int width = alph_dec->width_;
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int height = alph_dec->height_;
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WebPUnfilterFunc unfilter_func = WebPUnfilters[alph_dec->filter_];
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8_t* const output = dec->alpha_plane_;
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (alph_dec->method_ == ALPHA_NO_COMPRESSION) {
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const size_t offset = row * width;
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const size_t num_pixels = num_rows * width;
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    assert(dec->alpha_data_size_ >= ALPHA_HEADER_LEN + offset + num_pixels);
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    memcpy(dec->alpha_plane_ + offset,
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)           dec->alpha_data_ + ALPHA_HEADER_LEN + offset, num_pixels);
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {  // alph_dec->method_ == ALPHA_LOSSLESS_COMPRESSION
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    assert(alph_dec->vp8l_dec_ != NULL);
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!VP8LDecodeAlphaImageStream(alph_dec, row + num_rows)) {
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return 0;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (unfilter_func != NULL) {
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    unfilter_func(width, height, width, row, num_rows, output);
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (row + num_rows == dec->pic_hdr_.height_) {
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    dec->is_alpha_decoded_ = 1;
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return 1;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Main entry point.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      int row, int num_rows) {
122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const int width = dec->pic_hdr_.width_;
123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const int height = dec->pic_hdr_.height_;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (row < 0 || num_rows <= 0 || row + num_rows > height) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;    // sanity check.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (row == 0) {
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Initialize decoding.
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    assert(dec->alpha_plane_ != NULL);
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    dec->alph_dec_ = ALPHNew();
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (dec->alph_dec_ == NULL) return NULL;
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!ALPHInit(dec->alph_dec_, dec->alpha_data_, dec->alpha_data_size_,
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  width, height, dec->alpha_plane_)) {
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ALPHDelete(dec->alph_dec_);
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      dec->alph_dec_ = NULL;
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return NULL;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // if we allowed use of alpha dithering, check whether it's needed at all
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (dec->alph_dec_->pre_processing_ != ALPHA_PREPROCESSED_LEVELS) {
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      dec->alpha_dithering_ = 0;  // disable dithering
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    } else {
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      num_rows = height;          // decode everything in one pass
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!dec->is_alpha_decoded_) {
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int ok = 0;
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    assert(dec->alph_dec_ != NULL);
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ok = ALPHDecode(dec, row, num_rows);
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (ok && dec->alpha_dithering_ > 0) {
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ok = WebPDequantizeLevels(dec->alpha_plane_, width, height,
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                dec->alpha_dithering_);
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!ok || dec->is_alpha_decoded_) {
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ALPHDelete(dec->alph_dec_);
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      dec->alph_dec_ = NULL;
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!ok) return NULL;  // Error.
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return a pointer to the current decoded row.
164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return dec->alpha_plane_ + row * width;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
166