File: jpegmarkersegment.cpp

package info (click to toggle)
gdcm 3.0.21-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 26,880 kB
  • sloc: cpp: 203,477; ansic: 78,582; xml: 48,129; python: 3,459; cs: 2,308; java: 1,629; lex: 1,290; sh: 334; php: 128; makefile: 117
file content (117 lines) | stat: -rw-r--r-- 4,956 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//
// (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 <vector>
#include <cstdint>

using namespace std;
using namespace charls;

unique_ptr<JpegMarkerSegment> 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<uint8_t> content;
    content.push_back(static_cast<uint8_t>(bitsPerSample)); // P = Sample precision
    push_back(content, static_cast<uint16_t>(height));      // Y = Number of lines
    push_back(content, static_cast<uint16_t>(width));       // X = Number of samples per line

    // Components
    content.push_back(static_cast<uint8_t>(componentCount)); // Nf = Number of image components in frame
    for (auto component = 0; component < componentCount; ++component)
    {
        // Component Specification parameters
        content.push_back(static_cast<uint8_t>(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<JpegMarkerSegment>(JpegMarkerCode::StartOfFrameJpegLS, move(content));
}


unique_ptr<JpegMarkerSegment> 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<uint8_t> content { 'J', 'F', 'I', 'F', '\0' };
    push_back(content, static_cast<uint16_t>(params.version));
    content.push_back(static_cast<uint8_t>(params.units));
    push_back(content, static_cast<uint16_t>(params.Xdensity));
    push_back(content, static_cast<uint16_t>(params.Ydensity));

    // thumbnail
    content.push_back(static_cast<uint8_t>(params.Xthumbnail));
    content.push_back(static_cast<uint8_t>(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<uint8_t*>(params.thumbnail),
            static_cast<uint8_t*>(params.thumbnail) + 3 * params.Xthumbnail * params.Ythumbnail);
    }

    return make_unique<JpegMarkerSegment>(JpegMarkerCode::ApplicationData0, move(content));
}


unique_ptr<JpegMarkerSegment> JpegMarkerSegment::CreateJpegLSExtendedParametersSegment(const JlsCustomParameters& params)
{
    vector<uint8_t> content;

    // Parameter ID. 0x01 = JPEG-LS preset coding parameters.
    content.push_back(1);

    push_back(content, static_cast<uint16_t>(params.MAXVAL));
    push_back(content, static_cast<uint16_t>(params.T1));
    push_back(content, static_cast<uint16_t>(params.T2));
    push_back(content, static_cast<uint16_t>(params.T3));
    push_back(content, static_cast<uint16_t>(params.RESET));

    return make_unique<JpegMarkerSegment>(JpegMarkerCode::JpegLSExtendedParameters, move(content));
}


unique_ptr<JpegMarkerSegment> JpegMarkerSegment::CreateColorTransformSegment(ColorTransformation transformation)
{
    return make_unique<JpegMarkerSegment>(
        JpegMarkerCode::ApplicationData8,
        vector<uint8_t> { 'm', 'r', 'f', 'x', static_cast<uint8_t>(transformation) });
}


unique_ptr<JpegMarkerSegment> 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<uint8_t> content;

    content.push_back(static_cast<uint8_t>(componentCount));
    for (auto i = 0; i < componentCount; ++i)
    {
        content.push_back(static_cast<uint8_t>(componentIndex + i));
        content.push_back(0);  // Mapping table selector (0 = no table)
    }

    content.push_back(static_cast<uint8_t>(allowedLossyError)); // NEAR parameter
    content.push_back(static_cast<uint8_t>(interleaveMode)); // ILV parameter
    content.push_back(0); // transformation

    return make_unique<JpegMarkerSegment>(JpegMarkerCode::StartOfScan, move(content));
}