233class PT_GFX_API Yuv12 final :
public ImageFormat
240 static const Yuv12& get()
249 Pt::ssize_t pixelStride()
const
254 std::size_t imageSize(std::size_t width, std::size_t height,
255 std::size_t padding)
const
257 Pt::ssize_t stride = width + padding;
258 Pt::ssize_t planeSize = stride * height;
260 return planeSize + planeSize / 2;
264 virtual std::unique_ptr<ImageFormat> onClone()
const override
266 return std::unique_ptr<ImageFormat>(
new Yuv12);
269 virtual const std::type_info& onGetType()
const override
271 return typeid(*this);
274 virtual std::size_t onImageSize(Pt::ssize_t width, Pt::ssize_t height,
275 std::size_t padding)
const override;
278 Pt::ssize_t x, Pt::ssize_t y,
279 PixelStorage& store)
const override;
282 template <
typename T>
283 static void advance(T*& y, T*& u, T*& v,
285 Pt::ssize_t uvstride)
297 template <
typename T>
298 static void advanceN(T*& y, T*& u, T*& v,
302 Pt::ssize_t old_u_col = xpos / 2;
303 Pt::ssize_t new_u_col = (xpos + n) / 2;
308 Pt::ssize_t uv_diff = new_u_col - old_u_col;
313 template <
typename T>
314 static void skipPadding(T*& y, T*& u, T*& v,
315 Pt::ssize_t& xpos, Pt::ssize_t& ypos,
316 Pt::ssize_t padding, Pt::ssize_t uvstride)
332 template <
typename T>
333 static void advanceLines(T*& y, T*& u, T*& v,
337 Pt::ssize_t uvstride)
339 Pt::ssize_t old_u_row = ypos / 2;
340 Pt::ssize_t new_u_row = (ypos + n) / 2;
345 Pt::ssize_t uv_diff = (new_u_row - old_u_row) * uvstride;
353 const float ym =
static_cast<float>(y) - 16.f;
354 const float um =
static_cast<float>(u) - 128.f;
355 const float vm =
static_cast<float>(v) - 128.f;
356 const float scale = 1.f / 65535.f;
358 const float r = (298.f * ym + 409.f * vm + 128.f) * scale;
359 const float g = (298.f * ym - 100.f * um - 208.f * vm + 128.f) * scale;
360 const float b = (298.f * ym + 516.f * um + 128.f) * scale;
368 const float r = color.red() * 65535.f;
369 const float g = color.green() * 65535.f;
370 const float b = color.blue() * 65535.f;
371 const float scale = 1.f / 65536.f;
373 const float yy = ( 66.f * r + 129.f * g + 25.f * b + 128.f) * scale + 16.f;
374 const float uu = (-38.f * r - 74.f * g + 112.f * b + 128.f) * scale + 128.f;
375 const float vv = (112.f * r - 94.f * g - 18.f * b + 128.f) * scale + 128.f;
394 template <
typename T>
395 static Pt::ssize_t init(T* data, Pt::ssize_t stride,
396 Pt::ssize_t width, Pt::ssize_t height,
397 Pt::ssize_t xpos, Pt::ssize_t ypos,
400 Pt::ssize_t yOffset = stride * ypos + xpos;
403 return initUV(data, stride, width, height, xpos, ypos, u, v);
406 template <
typename T>
407 static Pt::ssize_t initUV(T* data, Pt::ssize_t stride,
408 Pt::ssize_t width, Pt::ssize_t height,
409 Pt::ssize_t xpos, Pt::ssize_t ypos,
412 Pt::ssize_t planeSize = stride * height;
414 Pt::ssize_t uvstride = stride / 2;
415 Pt::ssize_t subPlaneSize = planeSize / 4;
417 Pt::ssize_t subXPos = xpos / 2;
418 Pt::ssize_t subYPos = ypos / 2;
419 Pt::ssize_t subOffset = uvstride * subYPos + subXPos;
421 Pt::ssize_t uOffset = planeSize + subOffset;
424 Pt::ssize_t vOffset = uOffset + subPlaneSize;
430 template <
typename T>
431 static void advance(T*& y, T*& u, T*& v,
432 Pt::ssize_t& xpos, Pt::ssize_t& ypos,
433 Pt::ssize_t width, Pt::ssize_t padding,
434 Pt::ssize_t uvstride)
438 if( ++xpos >= width )
454 else if(xpos % 2 == 0)
461 template <
typename T>
462 static void advanceBy(T*& y, T*& u, T*& v, ssize_t n,
463 ssize_t& xpos, ssize_t& ypos, ssize_t width,
464 ssize_t ystride, ssize_t uvstride)
466 Pt::ssize_t new_abs_pos = (ypos * width) + xpos + n;
467 Pt::ssize_t new_ypos = new_abs_pos / width;
468 Pt::ssize_t new_xpos = new_abs_pos % width;
470 y += (new_ypos - ypos) * ystride + (new_xpos - xpos);
472 Pt::ssize_t old_u_row = ypos / 2;
473 Pt::ssize_t new_u_row = new_ypos / 2;
475 Pt::ssize_t old_u_col = xpos / 2;
476 Pt::ssize_t new_u_col = new_xpos / 2;
478 Pt::ssize_t uv_offset = (new_u_row - old_u_row) * uvstride + (new_u_col - old_u_col);