• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <cstring>
18 #include <cstdint>
19 #include <cmath>
20 
21 #include "ultrahdr/editorhelper.h"
22 
23 namespace ultrahdr {
24 
25 template <typename T>
rotate_buffer_clockwise(T * src_buffer,T * dst_buffer,int src_w,int src_h,int src_stride,int dst_stride,int degree)26 void rotate_buffer_clockwise(T* src_buffer, T* dst_buffer, int src_w, int src_h, int src_stride,
27                              int dst_stride, int degree) {
28   if (degree == 90) {
29     int dst_w = src_h;
30     int dst_h = src_w;
31     for (int i = 0; i < dst_h; i++) {
32       for (int j = 0; j < dst_w; j++) {
33         dst_buffer[i * dst_stride + j] = src_buffer[(src_h - j - 1) * src_stride + i];
34       }
35     }
36   } else if (degree == 180) {
37     int dst_w = src_w;
38     int dst_h = src_h;
39     for (int i = 0; i < dst_h; i++) {
40       for (int j = 0; j < dst_w; j++) {
41         dst_buffer[i * dst_stride + j] = src_buffer[(src_h - i - 1) * src_stride + (src_w - j - 1)];
42       }
43     }
44   } else if (degree == 270) {
45     int dst_w = src_h;
46     int dst_h = src_w;
47     for (int i = 0; i < dst_h; i++) {
48       for (int j = 0; j < dst_w; j++) {
49         dst_buffer[i * dst_stride + j] = src_buffer[j * src_stride + (src_w - i - 1)];
50       }
51     }
52   }
53 }
54 
55 template <typename T>
mirror_buffer(T * src_buffer,T * dst_buffer,int src_w,int src_h,int src_stride,int dst_stride,uhdr_mirror_direction_t direction)56 void mirror_buffer(T* src_buffer, T* dst_buffer, int src_w, int src_h, int src_stride,
57                    int dst_stride, uhdr_mirror_direction_t direction) {
58   if (direction == UHDR_MIRROR_VERTICAL) {
59     for (int i = 0; i < src_h; i++) {
60       memcpy(&dst_buffer[(src_h - i - 1) * dst_stride], &src_buffer[i * src_stride],
61              src_w * sizeof(T));
62     }
63   } else if (direction == UHDR_MIRROR_HORIZONTAL) {
64     for (int i = 0; i < src_h; i++) {
65       for (int j = 0; j < src_w; j++) {
66         dst_buffer[i * dst_stride + j] = src_buffer[i * src_stride + (src_w - j - 1)];
67       }
68     }
69   }
70 }
71 
72 // TODO (dichenzhang): legacy method, need to be removed
73 template <typename T>
resize_buffer(T * src_buffer,T * dst_buffer,int src_w,int src_h,int dst_w,int dst_h,int src_stride,int dst_stride)74 void resize_buffer(T* src_buffer, T* dst_buffer, int src_w, int src_h, int dst_w, int dst_h,
75                    int src_stride, int dst_stride) {
76   for (int i = 0; i < dst_h; i++) {
77     for (int j = 0; j < dst_w; j++) {
78       dst_buffer[i * dst_stride + j] =
79           src_buffer[i * (src_h / dst_h) * src_stride + j * (src_w / dst_w)];
80     }
81   }
82 }
83 
84 // This function performs bicubic interpolation on a 1D signal.
bicubic_interpolate(double p0,double p1,double p2,double p3,double x)85 double bicubic_interpolate(double p0, double p1, double p2, double p3, double x) {
86   // Calculate the weights for the four neighboring points.
87   double w0 = (1 - x) * (1 - x) * (1 - x);
88   double w1 = 3 * x * (1 - x) * (1 - x);
89   double w2 = 3 * x * x * (1 - x);
90   double w3 = x * x * x;
91 
92   // Calculate the interpolated value.
93   return w0 * p0 + w1 * p1 + w2 * p2 + w3 * p3;
94 }
95 
96 template <typename T>
resize_buffer(T * src_buffer,T * dst_buffer,int src_w,int src_h,int dst_w,int dst_h,int src_stride,int dst_stride,uhdr_img_fmt_t img_fmt,size_t plane)97 void resize_buffer(T* src_buffer, T* dst_buffer, int src_w, int src_h, int dst_w, int dst_h,
98                    int src_stride, int dst_stride, uhdr_img_fmt_t img_fmt, size_t plane) {
99   double scale_x = (double)src_w / dst_w;
100   double scale_y = (double)src_h / dst_h;
101   for (int y = 0; y < dst_h; y++) {
102     for (int x = 0; x < dst_w; x++) {
103       double ori_x = x * scale_x;
104       double ori_y = y * scale_y;
105       int p0_x = (int)floor(ori_x);
106       int p0_y = (int)floor(ori_y);
107       int p1_x = p0_x + 1;
108       int p1_y = p0_y;
109       int p2_x = p0_x;
110       int p2_y = p0_y + 1;
111       int p3_x = p0_x + 1;
112       int p3_y = p0_y + 1;
113 
114       if ((img_fmt == UHDR_IMG_FMT_8bppYCbCr400) ||
115           (img_fmt == UHDR_IMG_FMT_12bppYCbCr420 && plane == UHDR_PLANE_Y) ||
116           (img_fmt == UHDR_IMG_FMT_12bppYCbCr420 && plane == UHDR_PLANE_U) ||
117           (img_fmt == UHDR_IMG_FMT_12bppYCbCr420 && plane == UHDR_PLANE_V)) {
118         double p0 = (double)src_buffer[p0_y * src_stride + p0_x];
119         double p1 = (double)src_buffer[p1_y * src_stride + p1_x];
120         double p2 = (double)src_buffer[p2_y * src_stride + p2_x];
121         double p3 = (double)src_buffer[p3_y * src_stride + p3_x];
122 
123         double new_pix_val = bicubic_interpolate(p0, p1, p2, p3, ori_x - p0_x);
124 
125         dst_buffer[y * dst_stride + x] = (uint8_t)floor(new_pix_val + 0.5);
126       } else {
127         // Unsupported feature.
128         return;
129       }
130     }
131   }
132 }
133 
134 template void mirror_buffer<uint8_t>(uint8_t*, uint8_t*, int, int, int, int,
135                                      uhdr_mirror_direction_t);
136 template void mirror_buffer<uint16_t>(uint16_t*, uint16_t*, int, int, int, int,
137                                       uhdr_mirror_direction_t);
138 template void mirror_buffer<uint32_t>(uint32_t*, uint32_t*, int, int, int, int,
139                                       uhdr_mirror_direction_t);
140 template void mirror_buffer<uint64_t>(uint64_t*, uint64_t*, int, int, int, int,
141                                       uhdr_mirror_direction_t);
142 
143 template void rotate_buffer_clockwise<uint8_t>(uint8_t*, uint8_t*, int, int, int, int, int);
144 template void rotate_buffer_clockwise<uint16_t>(uint16_t*, uint16_t*, int, int, int, int, int);
145 template void rotate_buffer_clockwise<uint32_t>(uint32_t*, uint32_t*, int, int, int, int, int);
146 template void rotate_buffer_clockwise<uint64_t>(uint64_t*, uint64_t*, int, int, int, int, int);
147 
148 template void resize_buffer<uint8_t>(uint8_t*, uint8_t*, int, int, int, int, int, int);
149 template void resize_buffer<uint16_t>(uint16_t*, uint16_t*, int, int, int, int, int, int);
150 template void resize_buffer<uint32_t>(uint32_t*, uint32_t*, int, int, int, int, int, int);
151 template void resize_buffer<uint64_t>(uint64_t*, uint64_t*, int, int, int, int, int, int);
152 
uhdr_mirror_effect(uhdr_mirror_direction_t direction)153 uhdr_mirror_effect::uhdr_mirror_effect(uhdr_mirror_direction_t direction) : m_direction{direction} {
154 #if (defined(UHDR_ENABLE_INTRINSICS) && (defined(__ARM_NEON__) || defined(__ARM_NEON)))
155   m_mirror_uint8_t = mirror_buffer_neon<uint8_t>;
156   m_mirror_uint16_t = mirror_buffer_neon<uint16_t>;
157   m_mirror_uint32_t = mirror_buffer_neon<uint32_t>;
158   m_mirror_uint64_t = mirror_buffer_neon<uint64_t>;
159 #else
160   m_mirror_uint8_t = mirror_buffer<uint8_t>;
161   m_mirror_uint16_t = mirror_buffer<uint16_t>;
162   m_mirror_uint32_t = mirror_buffer<uint32_t>;
163   m_mirror_uint64_t = mirror_buffer<uint64_t>;
164 #endif
165 }
166 
uhdr_rotate_effect(int degree)167 uhdr_rotate_effect::uhdr_rotate_effect(int degree) : m_degree{degree} {
168 #if (defined(UHDR_ENABLE_INTRINSICS) && (defined(__ARM_NEON__) || defined(__ARM_NEON)))
169   m_rotate_uint8_t = rotate_buffer_clockwise_neon<uint8_t>;
170   m_rotate_uint16_t = rotate_buffer_clockwise_neon<uint16_t>;
171   m_rotate_uint32_t = rotate_buffer_clockwise_neon<uint32_t>;
172   m_rotate_uint64_t = rotate_buffer_clockwise_neon<uint64_t>;
173 #else
174   m_rotate_uint8_t = rotate_buffer_clockwise<uint8_t>;
175   m_rotate_uint16_t = rotate_buffer_clockwise<uint16_t>;
176   m_rotate_uint32_t = rotate_buffer_clockwise<uint32_t>;
177   m_rotate_uint64_t = rotate_buffer_clockwise<uint64_t>;
178 #endif
179 }
180 
uhdr_resize_effect(int width,int height)181 uhdr_resize_effect::uhdr_resize_effect(int width, int height) : m_width{width}, m_height{height} {
182   m_resize_uint8_t = resize_buffer<uint8_t>;
183   m_resize_uint16_t = resize_buffer<uint16_t>;
184   m_resize_uint32_t = resize_buffer<uint32_t>;
185   m_resize_uint64_t = resize_buffer<uint64_t>;
186 }
187 
apply_rotate(ultrahdr::uhdr_rotate_effect_t * desc,uhdr_raw_image_t * src)188 std::unique_ptr<uhdr_raw_image_ext_t> apply_rotate(ultrahdr::uhdr_rotate_effect_t* desc,
189                                                    uhdr_raw_image_t* src) {
190   std::unique_ptr<uhdr_raw_image_ext_t> dst;
191 
192   if (desc->m_degree == 90 || desc->m_degree == 270) {
193     dst = std::make_unique<uhdr_raw_image_ext_t>(src->fmt, src->cg, src->ct, src->range, src->h,
194                                                  src->w, 64);
195   } else if (desc->m_degree == 180) {
196     dst = std::make_unique<uhdr_raw_image_ext_t>(src->fmt, src->cg, src->ct, src->range, src->w,
197                                                  src->h, 64);
198   } else {
199     return nullptr;
200   }
201 
202   if (src->fmt == UHDR_IMG_FMT_24bppYCbCrP010) {
203     uint16_t* src_buffer = static_cast<uint16_t*>(src->planes[UHDR_PLANE_Y]);
204     uint16_t* dst_buffer = static_cast<uint16_t*>(dst->planes[UHDR_PLANE_Y]);
205     desc->m_rotate_uint16_t(src_buffer, dst_buffer, src->w, src->h, src->stride[UHDR_PLANE_Y],
206                             dst->stride[UHDR_PLANE_Y], desc->m_degree);
207     uint32_t* src_uv_buffer = static_cast<uint32_t*>(src->planes[UHDR_PLANE_UV]);
208     uint32_t* dst_uv_buffer = static_cast<uint32_t*>(dst->planes[UHDR_PLANE_UV]);
209     desc->m_rotate_uint32_t(src_uv_buffer, dst_uv_buffer, src->w / 2, src->h / 2,
210                             src->stride[UHDR_PLANE_UV] / 2, dst->stride[UHDR_PLANE_UV] / 2,
211                             desc->m_degree);
212   } else if (src->fmt == UHDR_IMG_FMT_12bppYCbCr420 || src->fmt == UHDR_IMG_FMT_8bppYCbCr400) {
213     uint8_t* src_buffer = static_cast<uint8_t*>(src->planes[UHDR_PLANE_Y]);
214     uint8_t* dst_buffer = static_cast<uint8_t*>(dst->planes[UHDR_PLANE_Y]);
215     desc->m_rotate_uint8_t(src_buffer, dst_buffer, src->w, src->h, src->stride[UHDR_PLANE_Y],
216                            dst->stride[UHDR_PLANE_Y], desc->m_degree);
217     if (src->fmt == UHDR_IMG_FMT_12bppYCbCr420) {
218       for (int i = 1; i < 3; i++) {
219         src_buffer = static_cast<uint8_t*>(src->planes[i]);
220         dst_buffer = static_cast<uint8_t*>(dst->planes[i]);
221         desc->m_rotate_uint8_t(src_buffer, dst_buffer, src->w / 2, src->h / 2, src->stride[i],
222                                dst->stride[i], desc->m_degree);
223       }
224     }
225   } else if (src->fmt == UHDR_IMG_FMT_32bppRGBA1010102 || src->fmt == UHDR_IMG_FMT_32bppRGBA8888) {
226     uint32_t* src_buffer = static_cast<uint32_t*>(src->planes[UHDR_PLANE_PACKED]);
227     uint32_t* dst_buffer = static_cast<uint32_t*>(dst->planes[UHDR_PLANE_PACKED]);
228     desc->m_rotate_uint32_t(src_buffer, dst_buffer, src->w, src->h, src->stride[UHDR_PLANE_PACKED],
229                             dst->stride[UHDR_PLANE_PACKED], desc->m_degree);
230   } else if (src->fmt == UHDR_IMG_FMT_64bppRGBAHalfFloat) {
231     uint64_t* src_buffer = static_cast<uint64_t*>(src->planes[UHDR_PLANE_PACKED]);
232     uint64_t* dst_buffer = static_cast<uint64_t*>(dst->planes[UHDR_PLANE_PACKED]);
233     desc->m_rotate_uint64_t(src_buffer, dst_buffer, src->w, src->h, src->stride[UHDR_PLANE_PACKED],
234                             dst->stride[UHDR_PLANE_PACKED], desc->m_degree);
235   }
236   return dst;
237 }
238 
apply_mirror(ultrahdr::uhdr_mirror_effect_t * desc,uhdr_raw_image_t * src)239 std::unique_ptr<uhdr_raw_image_ext_t> apply_mirror(ultrahdr::uhdr_mirror_effect_t* desc,
240                                                    uhdr_raw_image_t* src) {
241   std::unique_ptr<uhdr_raw_image_ext_t> dst = std::make_unique<uhdr_raw_image_ext_t>(
242       src->fmt, src->cg, src->ct, src->range, src->w, src->h, 64);
243 
244   if (src->fmt == UHDR_IMG_FMT_24bppYCbCrP010) {
245     uint16_t* src_buffer = static_cast<uint16_t*>(src->planes[UHDR_PLANE_Y]);
246     uint16_t* dst_buffer = static_cast<uint16_t*>(dst->planes[UHDR_PLANE_Y]);
247     desc->m_mirror_uint16_t(src_buffer, dst_buffer, src->w, src->h, src->stride[UHDR_PLANE_Y],
248                             dst->stride[UHDR_PLANE_Y], desc->m_direction);
249     uint32_t* src_uv_buffer = static_cast<uint32_t*>(src->planes[UHDR_PLANE_UV]);
250     uint32_t* dst_uv_buffer = static_cast<uint32_t*>(dst->planes[UHDR_PLANE_UV]);
251     desc->m_mirror_uint32_t(src_uv_buffer, dst_uv_buffer, src->w / 2, src->h / 2,
252                             src->stride[UHDR_PLANE_UV] / 2, dst->stride[UHDR_PLANE_UV] / 2,
253                             desc->m_direction);
254   } else if (src->fmt == UHDR_IMG_FMT_12bppYCbCr420 || src->fmt == UHDR_IMG_FMT_8bppYCbCr400) {
255     uint8_t* src_buffer = static_cast<uint8_t*>(src->planes[UHDR_PLANE_Y]);
256     uint8_t* dst_buffer = static_cast<uint8_t*>(dst->planes[UHDR_PLANE_Y]);
257     desc->m_mirror_uint8_t(src_buffer, dst_buffer, src->w, src->h, src->stride[UHDR_PLANE_Y],
258                            dst->stride[UHDR_PLANE_Y], desc->m_direction);
259     if (src->fmt == UHDR_IMG_FMT_12bppYCbCr420) {
260       for (int i = 1; i < 3; i++) {
261         src_buffer = static_cast<uint8_t*>(src->planes[i]);
262         dst_buffer = static_cast<uint8_t*>(dst->planes[i]);
263         desc->m_mirror_uint8_t(src_buffer, dst_buffer, src->w / 2, src->h / 2, src->stride[i],
264                                dst->stride[i], desc->m_direction);
265       }
266     }
267   } else if (src->fmt == UHDR_IMG_FMT_32bppRGBA1010102 || src->fmt == UHDR_IMG_FMT_32bppRGBA8888) {
268     uint32_t* src_buffer = static_cast<uint32_t*>(src->planes[UHDR_PLANE_PACKED]);
269     uint32_t* dst_buffer = static_cast<uint32_t*>(dst->planes[UHDR_PLANE_PACKED]);
270     desc->m_mirror_uint32_t(src_buffer, dst_buffer, src->w, src->h, src->stride[UHDR_PLANE_PACKED],
271                             dst->stride[UHDR_PLANE_PACKED], desc->m_direction);
272   } else if (src->fmt == UHDR_IMG_FMT_64bppRGBAHalfFloat) {
273     uint64_t* src_buffer = static_cast<uint64_t*>(src->planes[UHDR_PLANE_PACKED]);
274     uint64_t* dst_buffer = static_cast<uint64_t*>(dst->planes[UHDR_PLANE_PACKED]);
275     desc->m_mirror_uint64_t(src_buffer, dst_buffer, src->w, src->h, src->stride[UHDR_PLANE_PACKED],
276                             dst->stride[UHDR_PLANE_PACKED], desc->m_direction);
277   }
278   return dst;
279 }
280 
apply_crop(uhdr_raw_image_t * src,int left,int top,int wd,int ht)281 void apply_crop(uhdr_raw_image_t* src, int left, int top, int wd, int ht) {
282   if (src->fmt == UHDR_IMG_FMT_24bppYCbCrP010) {
283     uint16_t* src_buffer = static_cast<uint16_t*>(src->planes[UHDR_PLANE_Y]);
284     src->planes[UHDR_PLANE_Y] = &src_buffer[top * src->stride[UHDR_PLANE_Y] + left];
285     uint32_t* src_uv_buffer = static_cast<uint32_t*>(src->planes[UHDR_PLANE_UV]);
286     src->planes[UHDR_PLANE_UV] =
287         &src_uv_buffer[(top / 2) * (src->stride[UHDR_PLANE_UV] / 2) + (left / 2)];
288   } else if (src->fmt == UHDR_IMG_FMT_12bppYCbCr420 || src->fmt == UHDR_IMG_FMT_8bppYCbCr400) {
289     uint8_t* src_buffer = static_cast<uint8_t*>(src->planes[UHDR_PLANE_Y]);
290     src->planes[UHDR_PLANE_Y] = &src_buffer[top * src->stride[UHDR_PLANE_Y] + left];
291     if (src->fmt == UHDR_IMG_FMT_12bppYCbCr420) {
292       for (int i = 1; i < 3; i++) {
293         src_buffer = static_cast<uint8_t*>(src->planes[i]);
294         src->planes[i] = &src_buffer[(top / 2) * src->stride[i] + (left / 2)];
295       }
296     }
297   } else if (src->fmt == UHDR_IMG_FMT_32bppRGBA1010102 || src->fmt == UHDR_IMG_FMT_32bppRGBA8888) {
298     uint32_t* src_buffer = static_cast<uint32_t*>(src->planes[UHDR_PLANE_PACKED]);
299     src->planes[UHDR_PLANE_PACKED] = &src_buffer[top * src->stride[UHDR_PLANE_PACKED] + left];
300   } else if (src->fmt == UHDR_IMG_FMT_64bppRGBAHalfFloat) {
301     uint64_t* src_buffer = static_cast<uint64_t*>(src->planes[UHDR_PLANE_PACKED]);
302     src->planes[UHDR_PLANE_PACKED] = &src_buffer[top * src->stride[UHDR_PLANE_PACKED] + left];
303   }
304   src->w = wd;
305   src->h = ht;
306 }
307 
apply_resize(ultrahdr::uhdr_resize_effect_t * desc,uhdr_raw_image_t * src,int dst_w,int dst_h)308 std::unique_ptr<uhdr_raw_image_ext_t> apply_resize(ultrahdr::uhdr_resize_effect_t* desc,
309                                                    uhdr_raw_image_t* src, int dst_w, int dst_h) {
310   std::unique_ptr<uhdr_raw_image_ext_t> dst = std::make_unique<uhdr_raw_image_ext_t>(
311       src->fmt, src->cg, src->ct, src->range, dst_w, dst_h, 64);
312 
313   if (src->fmt == UHDR_IMG_FMT_24bppYCbCrP010) {
314     uint16_t* src_buffer = static_cast<uint16_t*>(src->planes[UHDR_PLANE_Y]);
315     uint16_t* dst_buffer = static_cast<uint16_t*>(dst->planes[UHDR_PLANE_Y]);
316     desc->m_resize_uint16_t(src_buffer, dst_buffer, src->w, src->h, dst->w, dst->h,
317                             src->stride[UHDR_PLANE_Y], dst->stride[UHDR_PLANE_Y]);
318     uint32_t* src_uv_buffer = static_cast<uint32_t*>(src->planes[UHDR_PLANE_UV]);
319     uint32_t* dst_uv_buffer = static_cast<uint32_t*>(dst->planes[UHDR_PLANE_UV]);
320     desc->m_resize_uint32_t(src_uv_buffer, dst_uv_buffer, src->w / 2, src->h / 2, dst->w / 2,
321                             dst->h / 2, src->stride[UHDR_PLANE_UV] / 2,
322                             dst->stride[UHDR_PLANE_UV] / 2);
323   } else if (src->fmt == UHDR_IMG_FMT_12bppYCbCr420 || src->fmt == UHDR_IMG_FMT_8bppYCbCr400) {
324     uint8_t* src_buffer = static_cast<uint8_t*>(src->planes[UHDR_PLANE_Y]);
325     uint8_t* dst_buffer = static_cast<uint8_t*>(dst->planes[UHDR_PLANE_Y]);
326     desc->m_resize_uint8_t(src_buffer, dst_buffer, src->w, src->h, dst->w, dst->h,
327                            src->stride[UHDR_PLANE_Y], dst->stride[UHDR_PLANE_Y]);
328     if (src->fmt == UHDR_IMG_FMT_12bppYCbCr420) {
329       for (int i = 1; i < 3; i++) {
330         src_buffer = static_cast<uint8_t*>(src->planes[i]);
331         dst_buffer = static_cast<uint8_t*>(dst->planes[i]);
332         desc->m_resize_uint8_t(src_buffer, dst_buffer, src->w / 2, src->h / 2, dst->w / 2,
333                                dst->h / 2, src->stride[i], dst->stride[i]);
334       }
335     }
336   } else if (src->fmt == UHDR_IMG_FMT_32bppRGBA1010102 || src->fmt == UHDR_IMG_FMT_32bppRGBA8888) {
337     uint32_t* src_buffer = static_cast<uint32_t*>(src->planes[UHDR_PLANE_PACKED]);
338     uint32_t* dst_buffer = static_cast<uint32_t*>(dst->planes[UHDR_PLANE_PACKED]);
339     desc->m_resize_uint32_t(src_buffer, dst_buffer, src->w, src->h, dst->w, dst->h,
340                             src->stride[UHDR_PLANE_PACKED], dst->stride[UHDR_PLANE_PACKED]);
341   } else if (src->fmt == UHDR_IMG_FMT_64bppRGBAHalfFloat) {
342     uint64_t* src_buffer = static_cast<uint64_t*>(src->planes[UHDR_PLANE_PACKED]);
343     uint64_t* dst_buffer = static_cast<uint64_t*>(dst->planes[UHDR_PLANE_PACKED]);
344     desc->m_resize_uint64_t(src_buffer, dst_buffer, src->w, src->h, dst->w, dst->h,
345                             src->stride[UHDR_PLANE_PACKED], dst->stride[UHDR_PLANE_PACKED]);
346   }
347   return dst;
348 }
349 
350 }  // namespace ultrahdr
351