arm_compute v18.05
[platform/upstream/armcl.git] / src / runtime / MultiImage.cpp
1 /*
2  * Copyright (c) 2016-2018 ARM Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #include "arm_compute/runtime/MultiImage.h"
25
26 #include "arm_compute/core/Error.h"
27 #include "arm_compute/core/TensorInfo.h"
28 #include "arm_compute/core/Utils.h"
29 #include "arm_compute/runtime/TensorAllocator.h"
30
31 using namespace arm_compute;
32
33 MultiImage::MultiImage()
34     : _info(), _plane()
35 {
36 }
37
38 const MultiImageInfo *MultiImage::info() const
39 {
40     return &_info;
41 }
42
43 void MultiImage::init(unsigned int width, unsigned int height, Format format)
44 {
45     internal_init(width, height, format, false);
46 }
47
48 void MultiImage::init_auto_padding(unsigned int width, unsigned int height, Format format)
49 {
50     internal_init(width, height, format, true);
51 }
52
53 void MultiImage::internal_init(unsigned int width, unsigned int height, Format format, bool auto_padding)
54 {
55     TensorShape shape = adjust_odd_shape(TensorShape{ width, height }, format);
56     TensorInfo  info(shape, Format::U8);
57
58     if(auto_padding)
59     {
60         info.auto_padding();
61     }
62
63     switch(format)
64     {
65         case Format::U8:
66         case Format::S16:
67         case Format::U16:
68         case Format::S32:
69         case Format::F16:
70         case Format::F32:
71         case Format::U32:
72         case Format::RGB888:
73         case Format::RGBA8888:
74         case Format::YUYV422:
75         case Format::UYVY422:
76         {
77             TensorInfo info_full(shape, format);
78
79             if(auto_padding)
80             {
81                 info_full.auto_padding();
82             }
83
84             std::get<0>(_plane).allocator()->init(info_full);
85             break;
86         }
87         case Format::NV12:
88         case Format::NV21:
89         {
90             const TensorShape shape_uv88 = calculate_subsampled_shape(shape, Format::UV88);
91             TensorInfo        info_uv88(shape_uv88, Format::UV88);
92
93             if(auto_padding)
94             {
95                 info_uv88.auto_padding();
96             }
97
98             std::get<0>(_plane).allocator()->init(info);
99             std::get<1>(_plane).allocator()->init(info_uv88);
100             break;
101         }
102         case Format::IYUV:
103         {
104             const TensorShape shape_sub2 = calculate_subsampled_shape(shape, Format::IYUV);
105             TensorInfo        info_sub2(shape_sub2, Format::U8);
106
107             if(auto_padding)
108             {
109                 info_sub2.auto_padding();
110             }
111
112             std::get<0>(_plane).allocator()->init(info);
113             std::get<1>(_plane).allocator()->init(info_sub2);
114             std::get<2>(_plane).allocator()->init(info_sub2);
115             break;
116         }
117         case Format::YUV444:
118             std::get<0>(_plane).allocator()->init(info);
119             std::get<1>(_plane).allocator()->init(info);
120             std::get<2>(_plane).allocator()->init(info);
121             break;
122         default:
123             ARM_COMPUTE_ERROR("Not supported");
124             break;
125     }
126
127     _info.init(shape.x(), shape.y(), format);
128 }
129
130 void MultiImage::allocate()
131 {
132     switch(_info.format())
133     {
134         case Format::U8:
135         case Format::S16:
136         case Format::U16:
137         case Format::S32:
138         case Format::F16:
139         case Format::F32:
140         case Format::U32:
141         case Format::RGB888:
142         case Format::RGBA8888:
143         case Format::YUYV422:
144         case Format::UYVY422:
145             std::get<0>(_plane).allocator()->allocate();
146             break;
147         case Format::NV12:
148         case Format::NV21:
149             std::get<0>(_plane).allocator()->allocate();
150             std::get<1>(_plane).allocator()->allocate();
151             break;
152         case Format::IYUV:
153         case Format::YUV444:
154             std::get<0>(_plane).allocator()->allocate();
155             std::get<1>(_plane).allocator()->allocate();
156             std::get<2>(_plane).allocator()->allocate();
157             break;
158         default:
159             ARM_COMPUTE_ERROR("Not supported");
160             break;
161     }
162 }
163
164 void MultiImage::create_subimage(MultiImage *image, const Coordinates &coords, unsigned int width, unsigned int height)
165 {
166     arm_compute::Format format = image->info()->format();
167     const TensorInfo    info(width, height, Format::U8);
168
169     switch(format)
170     {
171         case Format::U8:
172         case Format::S16:
173         case Format::U16:
174         case Format::S32:
175         case Format::F32:
176         case Format::F16:
177         case Format::U32:
178         case Format::RGB888:
179         case Format::RGBA8888:
180         case Format::YUYV422:
181         case Format::UYVY422:
182         {
183             const TensorInfo info_full(width, height, format);
184             std::get<0>(_plane).allocator()->init(*dynamic_cast<Image *>(image->plane(0))->allocator(), coords, info_full);
185             break;
186         }
187         case Format::NV12:
188         case Format::NV21:
189         {
190             const TensorInfo info_uv88(width / 2, height / 2, Format::UV88);
191             std::get<0>(_plane).allocator()->init(*dynamic_cast<Image *>(image->plane(0))->allocator(), coords, info);
192             std::get<1>(_plane).allocator()->init(*dynamic_cast<Image *>(image->plane(1))->allocator(), coords, info_uv88);
193             break;
194         }
195         case Format::IYUV:
196         {
197             const TensorInfo info_sub2(width / 2, height / 2, Format::U8);
198             std::get<0>(_plane).allocator()->init(*dynamic_cast<Image *>(image->plane(0))->allocator(), coords, info);
199             std::get<1>(_plane).allocator()->init(*dynamic_cast<Image *>(image->plane(1))->allocator(), coords, info_sub2);
200             std::get<2>(_plane).allocator()->init(*dynamic_cast<Image *>(image->plane(2))->allocator(), coords, info_sub2);
201             break;
202         }
203         case Format::YUV444:
204             std::get<0>(_plane).allocator()->init(*dynamic_cast<Image *>(image->plane(0))->allocator(), coords, info);
205             std::get<1>(_plane).allocator()->init(*dynamic_cast<Image *>(image->plane(0))->allocator(), coords, info);
206             std::get<2>(_plane).allocator()->init(*dynamic_cast<Image *>(image->plane(0))->allocator(), coords, info);
207             break;
208         default:
209             ARM_COMPUTE_ERROR("Not supported");
210             break;
211     }
212
213     _info.init(width, height, format);
214 }
215
216 Image *MultiImage::plane(unsigned int index)
217 {
218     return &_plane[index];
219 }
220
221 const Image *MultiImage::plane(unsigned int index) const
222 {
223     return &_plane[index];
224 }