summaryrefslogtreecommitdiff
path: root/indra/llkdu/llimagej2ckdu.h
blob: 8037c818687dcc5d8e9478ccf2c573b83aad7903 (plain)
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/**
 * @file llimagej2ckdu.h
 * @brief This is an implementation of JPEG2000 encode/decode using Kakadu
 *
 * $LicenseInfo:firstyear=2010&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#ifndef LL_LLIMAGEJ2CKDU_H
#define LL_LLIMAGEJ2CKDU_H

#include "llimagej2c.h"

//
// KDU core header files
//
#define KDU_NO_THREADS
#include "kdu_elementary.h"
#include "kdu_messaging.h"
#include "kdu_params.h"

#define kdu_xxxx "kdu_compressed.h"
#include "include_kdu_xxxx.h"

#include "kdu_sample_processing.h"
#include <boost/scoped_ptr.hpp>
#include <boost/noncopyable.hpp>

class LLKDUDecodeState;
class LLKDUMemSource;

class LLImageJ2CKDU : public LLImageJ2CImpl
{
public:
    enum ECodeStreamMode
    {
        MODE_FAST = 0,
        MODE_RESILIENT = 1,
        MODE_FUSSY = 2
    };
    LLImageJ2CKDU();
    virtual ~LLImageJ2CKDU();

protected:
    virtual bool getMetadata(LLImageJ2C &base);
    virtual bool decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count);
    virtual bool encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,
                                bool reversible=false);
    virtual bool initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL);
    virtual bool initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0);
    virtual std::string getEngineInfo() const;

private:
    bool initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level = -1, int* region = NULL);
    void setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECodeStreamMode mode);
    void cleanupCodeStream();

    // This method was public, but the only call to it is commented out in our
    // own initDecode() method. I (nat 2016-08-04) don't know what it does or
    // why. Even if it should be uncommented, it should probably still be
    // private.
//  void findDiscardLevelsBoundaries(LLImageJ2C &base);

    // Helper class to hold a kdu_codestream, which is a handle to the
    // underlying implementation object. When CodeStreamHolder is reset() or
    // destroyed, it calls kdu_codestream::destroy() -- which kdu_codestream
    // itself does not.
    //
    // Call through it like a smart pointer using operator->().
    //
    // Every RAII class must be noncopyable. For this we don't need move
    // support.
    class CodeStreamHolder: public boost::noncopyable
    {
    public:
        ~CodeStreamHolder()
        {
            reset();
        }

        void reset()
        {
            if (mCodeStream.exists())
            {
                mCodeStream.destroy();
            }
        }

        // for those few times when you need a raw kdu_codestream*
        kdu_core::kdu_codestream* get() { return &mCodeStream; }
        kdu_core::kdu_codestream* operator->() { return &mCodeStream; }

    private:
        kdu_core::kdu_codestream mCodeStream;
    };

    // Encode variable
    std::unique_ptr<LLKDUMemSource> mInputp;
    CodeStreamHolder mCodeStreamp;
    std::unique_ptr<kdu_core::kdu_coords> mTPosp; // tile position
    std::unique_ptr<kdu_core::kdu_dims> mTileIndicesp;
    int mBlocksSize;
    int mPrecinctsSize;
    int mLevels;

    // Temporary variables for in-progress decodes...
    // We don't own this LLImageRaw. We're simply pointing to an instance
    // passed into initDecode().
    LLImageRaw *mRawImagep;
    std::unique_ptr<LLKDUDecodeState> mDecodeState;
};

#endif