summaryrefslogtreecommitdiff
path: root/gpr/source/lib/vc5_decoder/wavelet.c
diff options
context:
space:
mode:
Diffstat (limited to 'gpr/source/lib/vc5_decoder/wavelet.c')
-rwxr-xr-xgpr/source/lib/vc5_decoder/wavelet.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/gpr/source/lib/vc5_decoder/wavelet.c b/gpr/source/lib/vc5_decoder/wavelet.c
new file mode 100755
index 0000000..a60eb0a
--- /dev/null
+++ b/gpr/source/lib/vc5_decoder/wavelet.c
@@ -0,0 +1,173 @@
+/*! @file wavelet.c
+ *
+ * @brief Implementation of the module for wavelet data structures and transforms
+ *
+ * @version 1.0.0
+ *
+ * (C) Copyright 2018 GoPro Inc (http://gopro.com/).
+ *
+ * Licensed under either:
+ * - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
+ * - MIT license, http://opensource.org/licenses/MIT
+ * at your option.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "headers.h"
+
+/*!
+ @brief Apply the inverse wavelet transform to reconstruct a lowpass band
+
+ This routine reconstructs the lowpass band in the output wavelet from the
+ decoded bands in the input wavelet. The prescale argument is used to undo
+ scaling that may have been performed during encoding to prevent overflow.
+
+ @todo Replace the two different routines for different prescale shifts with
+ a single routine that can handle any prescale shift.
+*/
+CODEC_ERROR TransformInverseSpatialQuantLowpass(gpr_allocator *allocator, WAVELET *input, WAVELET *output, uint16_t prescale)
+{
+ // Dimensions of each wavelet band
+ DIMENSION input_width = input->width;
+ DIMENSION input_height = input->height;
+
+ // The output width may be less than twice the input width if the output width is odd
+ DIMENSION output_width = output->width;
+
+ // The output height may be less than twice the input height if the output height is odd
+ DIMENSION output_height = output->height;
+
+ // Check that a valid input image has been provided
+ assert(input != NULL);
+ assert(input->data[0] != NULL);
+ assert(input->data[1] != NULL);
+ assert(input->data[2] != NULL);
+ assert(input->data[3] != NULL);
+
+ // Check that the output image is a gray image or a lowpass wavelet band
+ assert(output->data[0] != NULL);
+
+ // Check for valid quantization values
+ if (input->quant[0] == 0) {
+ input->quant[0] = 1;
+ }
+
+ assert(input->quant[0] > 0);
+ assert(input->quant[1] > 0);
+ assert(input->quant[2] > 0);
+ assert(input->quant[3] > 0);
+
+ if (prescale > 1)
+ {
+ // This is a spatial transform for the lowpass temporal band
+ assert(prescale == 2);
+
+ // Apply the inverse spatial transform for a lowpass band that is not prescaled
+ InvertSpatialQuantDescale16s(allocator,
+ (PIXEL *)input->data[0], input->pitch,
+ (PIXEL *)input->data[1], input->pitch,
+ (PIXEL *)input->data[2], input->pitch,
+ (PIXEL *)input->data[3], input->pitch,
+ output->data[0], output->pitch,
+ input_width, input_height,
+ output_width, output_height,
+ prescale, input->quant);
+ }
+ else
+ {
+ // This case does not handle any prescaling applied during encoding
+ assert(prescale == 0);
+
+ // Apply the inverse spatial transform for a lowpass band that is not prescaled
+ InvertSpatialQuant16s(allocator,
+ (PIXEL *)input->data[0], input->pitch,
+ (PIXEL *)input->data[1], input->pitch,
+ (PIXEL *)input->data[2], input->pitch,
+ (PIXEL *)input->data[3], input->pitch,
+ output->data[0], output->pitch,
+ input_width, input_height,
+ output_width, output_height,
+ input->quant);
+ }
+
+ return CODEC_ERROR_OKAY;
+}
+
+/*!
+ @brief Apply the inverse wavelet transform to reconstruct a component array
+
+ This routine reconstructs the lowpass band in the output wavelet from the
+ decoded bands in the input wavelet. The prescale argument is used to undo
+ scaling that may have been performed during encoding to prevent overflow.
+*/
+CODEC_ERROR TransformInverseSpatialQuantArray(gpr_allocator *allocator,
+ WAVELET *input,
+ COMPONENT_VALUE *output_buffer,
+ DIMENSION output_width,
+ DIMENSION output_height,
+ size_t output_pitch,
+ PRESCALE prescale)
+{
+ // Dimensions of each wavelet band
+ DIMENSION input_width = input->width;
+ DIMENSION input_height = input->height;
+
+ // Check that a valid input image has been provided
+ assert(input != NULL);
+ assert(input->data[0] != NULL);
+ assert(input->data[1] != NULL);
+ assert(input->data[2] != NULL);
+ assert(input->data[3] != NULL);
+
+ // Check for valid quantization values
+ if (input->quant[0] == 0) {
+ input->quant[0] = 1;
+ }
+
+ assert(input->quant[0] > 0);
+ assert(input->quant[1] > 0);
+ assert(input->quant[2] > 0);
+ assert(input->quant[3] > 0);
+
+ assert(output_width > 0 && output_height > 0 && output_pitch > 0 && output_buffer != NULL);
+
+ if (prescale > 1)
+ {
+ // This is a spatial transform for the lowpass temporal band
+ assert(prescale == 2);
+
+ // Apply the inverse spatial transform for a lowpass band that is not prescaled
+ InvertSpatialQuantDescale16s(allocator,
+ (PIXEL *)input->data[0], input->pitch,
+ (PIXEL *)input->data[1], input->pitch,
+ (PIXEL *)input->data[2], input->pitch,
+ (PIXEL *)input->data[3], input->pitch,
+ (PIXEL *)output_buffer, (int)output_pitch,
+ input_width, input_height,
+ output_width, output_height,
+ prescale, input->quant);
+ }
+ else
+ {
+ // This case does not handle any prescaling applied during encoding
+ assert(prescale == 0);
+
+ // Apply the inverse spatial transform for a lowpass band that is not prescaled
+ InvertSpatialQuant16s(allocator,
+ (PIXEL *)input->data[0], input->pitch,
+ (PIXEL *)input->data[1], input->pitch,
+ (PIXEL *)input->data[2], input->pitch,
+ (PIXEL *)input->data[3], input->pitch,
+ (PIXEL *)output_buffer, (int)output_pitch,
+ input_width, input_height,
+ output_width, output_height,
+ input->quant);
+ }
+
+ return CODEC_ERROR_OKAY;
+}