// // (C) CharLS Team 2014, all rights reserved. See the accompanying "License.txt" for licensed use. // #include "jpegmarkersegment.h" #include "jpegmarkercode.h" #include "util.h" #include #include using namespace std; using namespace charls; unique_ptr JpegMarkerSegment::CreateStartOfFrameSegment(int width, int height, int bitsPerSample, int componentCount) { ASSERT(width >= 0 && width <= UINT16_MAX); ASSERT(height >= 0 && height <= UINT16_MAX); ASSERT(bitsPerSample > 0 && bitsPerSample <= UINT8_MAX); ASSERT(componentCount > 0 && componentCount <= (UINT8_MAX - 1)); // Create a Frame Header as defined in T.87, C.2.2 and T.81, B.2.2 vector content; content.push_back(static_cast(bitsPerSample)); // P = Sample precision push_back(content, static_cast(height)); // Y = Number of lines push_back(content, static_cast(width)); // X = Number of samples per line // Components content.push_back(static_cast(componentCount)); // Nf = Number of image components in frame for (auto component = 0; component < componentCount; ++component) { // Component Specification parameters content.push_back(static_cast(component + 1)); // Ci = Component identifier content.push_back(0x11); // Hi + Vi = Horizontal sampling factor + Vertical sampling factor content.push_back(0); // Tqi = Quantization table destination selector (reserved for JPEG-LS, should be set to 0) } return make_unique(JpegMarkerCode::StartOfFrameJpegLS, move(content)); } unique_ptr JpegMarkerSegment::CreateJpegFileInterchangeFormatSegment(const JfifParameters& params) { ASSERT(params.units == 0 || params.units == 1 || params.units == 2); ASSERT(params.Xdensity > 0); ASSERT(params.Ydensity > 0); ASSERT(params.Xthumbnail >= 0 && params.Xthumbnail < 256); ASSERT(params.Ythumbnail >= 0 && params.Ythumbnail < 256); // Create a JPEG APP0 segment in the JPEG File Interchange Format (JFIF), v1.02 vector content { 'J', 'F', 'I', 'F', '\0' }; push_back(content, static_cast(params.version)); content.push_back(static_cast(params.units)); push_back(content, static_cast(params.Xdensity)); push_back(content, static_cast(params.Ydensity)); // thumbnail content.push_back(static_cast(params.Xthumbnail)); content.push_back(static_cast(params.Ythumbnail)); if (params.Xthumbnail > 0) { if (params.thumbnail) throw CreateSystemError(ApiResult::InvalidJlsParameters, "params.Xthumbnail is > 0 but params.thumbnail == null_ptr"); content.insert(content.end(), static_cast(params.thumbnail), static_cast(params.thumbnail) + 3 * params.Xthumbnail * params.Ythumbnail); } return make_unique(JpegMarkerCode::ApplicationData0, move(content)); } unique_ptr JpegMarkerSegment::CreateJpegLSExtendedParametersSegment(const JlsCustomParameters& params) { vector content; // Parameter ID. 0x01 = JPEG-LS preset coding parameters. content.push_back(1); push_back(content, static_cast(params.MAXVAL)); push_back(content, static_cast(params.T1)); push_back(content, static_cast(params.T2)); push_back(content, static_cast(params.T3)); push_back(content, static_cast(params.RESET)); return make_unique(JpegMarkerCode::JpegLSExtendedParameters, move(content)); } unique_ptr JpegMarkerSegment::CreateColorTransformSegment(ColorTransformation transformation) { return make_unique( JpegMarkerCode::ApplicationData8, vector { 'm', 'r', 'f', 'x', static_cast(transformation) }); } unique_ptr JpegMarkerSegment::CreateStartOfScanSegment(int componentIndex, int componentCount, int allowedLossyError, InterleaveMode interleaveMode) { ASSERT(componentIndex >= 0); ASSERT(componentCount > 0); // Create a Scan Header as defined in T.87, C.2.3 and T.81, B.2.3 vector content; content.push_back(static_cast(componentCount)); for (auto i = 0; i < componentCount; ++i) { content.push_back(static_cast(componentIndex + i)); content.push_back(0); // Mapping table selector (0 = no table) } content.push_back(static_cast(allowedLossyError)); // NEAR parameter content.push_back(static_cast(interleaveMode)); // ILV parameter content.push_back(0); // transformation return make_unique(JpegMarkerCode::StartOfScan, move(content)); }