updated copyright.
[platform/core/graphics/tizenvg.git] / src / loaders / external_jpg / tvgJpgLoader.cpp
1 /*
2  * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved.
3
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10
11  * The above copyright notice and this permission notice shall be included in all
12  * copies or substantial portions of the Software.
13
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  */
22
23 #include <memory.h>
24 #include <turbojpeg.h>
25 #include "tvgLoader.h"
26 #include "tvgJpgLoader.h"
27
28 /************************************************************************/
29 /* Internal Class Implementation                                        */
30 /************************************************************************/
31
32 void JpgLoader::clear()
33 {
34     if (freeData) free(data);
35     data = nullptr;
36     size = 0;
37     freeData = false;
38 }
39
40 /************************************************************************/
41 /* External Class Implementation                                        */
42 /************************************************************************/
43
44 JpgLoader::JpgLoader()
45 {
46     jpegDecompressor = tjInitDecompress();
47 }
48
49
50 JpgLoader::~JpgLoader()
51 {
52     if (freeData) free(data);
53     tjDestroy(jpegDecompressor);
54
55     //This image is shared with raster engine.
56     tjFree(image);
57 }
58
59
60 bool JpgLoader::open(const string& path)
61 {
62     clear();
63
64     auto jpegFile = fopen(path.c_str(), "rb");
65     if (!jpegFile) return false;
66
67     auto ret = false;
68
69     //determine size
70     if (fseek(jpegFile, 0, SEEK_END) < 0) goto finalize;
71     if (((size = ftell(jpegFile)) < 1)) goto finalize;
72     if (fseek(jpegFile, 0, SEEK_SET)) goto finalize;
73
74     data = (unsigned char *) malloc(size);
75     if (!data) goto finalize;
76
77     freeData = true;
78
79     if (fread(data, size, 1, jpegFile) < 1) goto failure;
80
81     int width, height, subSample, colorSpace;
82     if (tjDecompressHeader3(jpegDecompressor, data, size, &width, &height, &subSample, &colorSpace) < 0) {
83         TVGERR("JPG LOADER", "%s", tjGetErrorStr());
84         goto failure;
85     }
86
87     w = static_cast<float>(width);
88     h = static_cast<float>(height);
89     ret = true;
90
91     goto finalize;
92
93 failure:
94     clear();
95
96 finalize:
97     fclose(jpegFile);
98     return ret;
99 }
100
101
102 bool JpgLoader::open(const char* data, uint32_t size, bool copy)
103 {
104     clear();
105
106     int width, height, subSample, colorSpace;
107     if (tjDecompressHeader3(jpegDecompressor, (unsigned char *) data, size, &width, &height, &subSample, &colorSpace) < 0) return false;
108
109     if (copy) {
110         this->data = (unsigned char *) malloc(size);
111         if (!this->data) return false;
112         memcpy((unsigned char *)this->data, data, size);
113         freeData = true;
114     } else {
115         this->data = (unsigned char *) data;
116         freeData = false;
117     }
118
119     w = static_cast<float>(width);
120     h = static_cast<float>(height);
121     this->size = size;
122
123     return true;
124 }
125
126
127 bool JpgLoader::read()
128 {
129     if (image) tjFree(image);
130     image = (unsigned char *)tjAlloc(static_cast<int>(w) * static_cast<int>(h) * tjPixelSize[TJPF_BGRX]);
131     if (!image) return false;
132
133     //decompress jpg image
134     if (tjDecompress2(jpegDecompressor, data, size, image, static_cast<int>(w), 0, static_cast<int>(h), TJPF_BGRX, 0) < 0) {
135         TVGERR("JPG LOADER", "%s", tjGetErrorStr());
136         tjFree(image);
137         image = nullptr;
138         return false;
139     }
140
141     return true;
142 }
143
144
145 bool JpgLoader::close()
146 {
147     clear();
148     return true;
149 }
150
151
152 unique_ptr<Surface> JpgLoader::bitmap()
153 {
154     if (!image) return nullptr;
155
156     auto surface = static_cast<Surface*>(malloc(sizeof(Surface)));
157     surface->buffer = (uint32_t*)(image);
158     surface->stride = w;
159     surface->w = w;
160     surface->h = h;
161     surface->cs = SwCanvas::ARGB8888;
162
163     return unique_ptr<Surface>(surface);
164 }