|  | // Copyright (c) 2016 The WebM project authors. All Rights Reserved. | 
|  | // | 
|  | // Use of this source code is governed by a BSD-style license | 
|  | // that can be found in the LICENSE file in the root of the source | 
|  | // tree. An additional intellectual property rights grant can be found | 
|  | // in the file PATENTS.  All contributing project authors may | 
|  | // be found in the AUTHORS file in the root of the source tree. | 
|  | #include "hdr_util.h" | 
|  |  | 
|  | #include <cstddef> | 
|  | #include <new> | 
|  |  | 
|  | #include "mkvparser/mkvparser.h" | 
|  |  | 
|  | namespace libwebm { | 
|  | bool CopyPrimaryChromaticity(const mkvparser::PrimaryChromaticity& parser_pc, | 
|  | PrimaryChromaticityPtr* muxer_pc) { | 
|  | muxer_pc->reset(new (std::nothrow) | 
|  | mkvmuxer::PrimaryChromaticity(parser_pc.x, parser_pc.y)); | 
|  | if (!muxer_pc->get()) | 
|  | return false; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | bool MasteringMetadataValuePresent(double value) { | 
|  | return value != mkvparser::MasteringMetadata::kValueNotPresent; | 
|  | } | 
|  |  | 
|  | bool CopyMasteringMetadata(const mkvparser::MasteringMetadata& parser_mm, | 
|  | mkvmuxer::MasteringMetadata* muxer_mm) { | 
|  | if (MasteringMetadataValuePresent(parser_mm.luminance_max)) | 
|  | muxer_mm->luminance_max = parser_mm.luminance_max; | 
|  | if (MasteringMetadataValuePresent(parser_mm.luminance_min)) | 
|  | muxer_mm->luminance_min = parser_mm.luminance_min; | 
|  |  | 
|  | PrimaryChromaticityPtr r_ptr(NULL); | 
|  | PrimaryChromaticityPtr g_ptr(NULL); | 
|  | PrimaryChromaticityPtr b_ptr(NULL); | 
|  | PrimaryChromaticityPtr wp_ptr(NULL); | 
|  |  | 
|  | if (parser_mm.r) { | 
|  | if (!CopyPrimaryChromaticity(*parser_mm.r, &r_ptr)) | 
|  | return false; | 
|  | } | 
|  | if (parser_mm.g) { | 
|  | if (!CopyPrimaryChromaticity(*parser_mm.g, &g_ptr)) | 
|  | return false; | 
|  | } | 
|  | if (parser_mm.b) { | 
|  | if (!CopyPrimaryChromaticity(*parser_mm.b, &b_ptr)) | 
|  | return false; | 
|  | } | 
|  | if (parser_mm.white_point) { | 
|  | if (!CopyPrimaryChromaticity(*parser_mm.white_point, &wp_ptr)) | 
|  | return false; | 
|  | } | 
|  |  | 
|  | if (!muxer_mm->SetChromaticity(r_ptr.get(), g_ptr.get(), b_ptr.get(), | 
|  | wp_ptr.get())) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | return true; | 
|  | } | 
|  |  | 
|  | bool ColourValuePresent(long long value) { | 
|  | return value != mkvparser::Colour::kValueNotPresent; | 
|  | } | 
|  |  | 
|  | bool CopyColour(const mkvparser::Colour& parser_colour, | 
|  | mkvmuxer::Colour* muxer_colour) { | 
|  | if (!muxer_colour) | 
|  | return false; | 
|  |  | 
|  | if (ColourValuePresent(parser_colour.matrix_coefficients)) | 
|  | muxer_colour->matrix_coefficients = parser_colour.matrix_coefficients; | 
|  | if (ColourValuePresent(parser_colour.bits_per_channel)) | 
|  | muxer_colour->bits_per_channel = parser_colour.bits_per_channel; | 
|  | if (ColourValuePresent(parser_colour.chroma_subsampling_horz)) | 
|  | muxer_colour->chroma_subsampling_horz = | 
|  | parser_colour.chroma_subsampling_horz; | 
|  | if (ColourValuePresent(parser_colour.chroma_subsampling_vert)) | 
|  | muxer_colour->chroma_subsampling_vert = | 
|  | parser_colour.chroma_subsampling_vert; | 
|  | if (ColourValuePresent(parser_colour.cb_subsampling_horz)) | 
|  | muxer_colour->cb_subsampling_horz = parser_colour.cb_subsampling_horz; | 
|  | if (ColourValuePresent(parser_colour.cb_subsampling_vert)) | 
|  | muxer_colour->cb_subsampling_vert = parser_colour.cb_subsampling_vert; | 
|  | if (ColourValuePresent(parser_colour.chroma_siting_horz)) | 
|  | muxer_colour->chroma_siting_horz = parser_colour.chroma_siting_horz; | 
|  | if (ColourValuePresent(parser_colour.chroma_siting_vert)) | 
|  | muxer_colour->chroma_siting_vert = parser_colour.chroma_siting_vert; | 
|  | if (ColourValuePresent(parser_colour.range)) | 
|  | muxer_colour->range = parser_colour.range; | 
|  | if (ColourValuePresent(parser_colour.transfer_characteristics)) | 
|  | muxer_colour->transfer_characteristics = | 
|  | parser_colour.transfer_characteristics; | 
|  | if (ColourValuePresent(parser_colour.primaries)) | 
|  | muxer_colour->primaries = parser_colour.primaries; | 
|  | if (ColourValuePresent(parser_colour.max_cll)) | 
|  | muxer_colour->max_cll = parser_colour.max_cll; | 
|  | if (ColourValuePresent(parser_colour.max_fall)) | 
|  | muxer_colour->max_fall = parser_colour.max_fall; | 
|  |  | 
|  | if (parser_colour.mastering_metadata) { | 
|  | mkvmuxer::MasteringMetadata muxer_mm; | 
|  | if (!CopyMasteringMetadata(*parser_colour.mastering_metadata, &muxer_mm)) | 
|  | return false; | 
|  | if (!muxer_colour->SetMasteringMetadata(muxer_mm)) | 
|  | return false; | 
|  | } | 
|  | return true; | 
|  | } | 
|  |  | 
|  | // Format of VPx private data: | 
|  | // | 
|  | //   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 
|  | //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 
|  | //  |    ID Byte    |             Length            |               | | 
|  | //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               | | 
|  | //  |                                                               | | 
|  | //  :               Bytes 1..Length of Codec Feature                : | 
|  | //  |                                                               | | 
|  | //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 
|  | // | 
|  | // ID Byte Format | 
|  | // ID byte is an unsigned byte. | 
|  | //   0 1 2 3 4 5 6 7 | 
|  | //  +-+-+-+-+-+-+-+-+ | 
|  | //  |X|    ID       | | 
|  | //  +-+-+-+-+-+-+-+-+ | 
|  | // | 
|  | // The X bit is reserved. | 
|  | // | 
|  | // Currently only profile level is supported. ID byte must be set to 1, and | 
|  | // length must be 1. Supported values are: | 
|  | // | 
|  | //   10: Level 1 | 
|  | //   11: Level 1.1 | 
|  | //   20: Level 2 | 
|  | //   21: Level 2.1 | 
|  | //   30: Level 3 | 
|  | //   31: Level 3.1 | 
|  | //   40: Level 4 | 
|  | //   41: Level 4.1 | 
|  | //   50: Level 5 | 
|  | //   51: Level 5.1 | 
|  | //   52: Level 5.2 | 
|  | //   60: Level 6 | 
|  | //   61: Level 6.1 | 
|  | //   62: Level 6.2 | 
|  | // | 
|  | // See the following link for more information: | 
|  | // http://www.webmproject.org/vp9/profiles/ | 
|  | int ParseVpxCodecPrivate(const uint8_t* private_data, int32_t length) { | 
|  | const int kVpxCodecPrivateLength = 3; | 
|  | if (!private_data || length != kVpxCodecPrivateLength) | 
|  | return 0; | 
|  |  | 
|  | const uint8_t id_byte = *private_data; | 
|  | if (id_byte != 1) | 
|  | return 0; | 
|  |  | 
|  | const int kVpxProfileLength = 1; | 
|  | const uint8_t length_byte = private_data[1]; | 
|  | if (length_byte != kVpxProfileLength) | 
|  | return 0; | 
|  |  | 
|  | const int level = static_cast<int>(private_data[2]); | 
|  |  | 
|  | const int kNumLevels = 14; | 
|  | const int levels[kNumLevels] = {10, 11, 20, 21, 30, 31, 40, | 
|  | 41, 50, 51, 52, 60, 61, 62}; | 
|  |  | 
|  | for (int i = 0; i < kNumLevels; ++i) { | 
|  | if (level == levels[i]) | 
|  | return level; | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } | 
|  | }  // namespace libwebm |