1f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang/* 2f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang * Copyright 2011 The LibYuv Project Authors. All rights reserved. 3f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang * 4f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang * Use of this source code is governed by a BSD-style license 5f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang * that can be found in the LICENSE file in the root of the source 6f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang * tree. An additional intellectual property rights grant can be found 7f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang * in the file PATENTS. All contributing project authors may 8f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang * be found in the AUTHORS file in the root of the source tree. 9f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang */ 10f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 11f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#include "libyuv/convert_argb.h" 12f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 13f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#include "libyuv/cpu_id.h" 14f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#ifdef HAVE_JPEG 15f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#include "libyuv/mjpeg_decoder.h" 16f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#endif 17f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#include "libyuv/rotate_argb.h" 18f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#include "libyuv/row.h" 19f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#include "libyuv/video_common.h" 20f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 21f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#ifdef __cplusplus 22f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangnamespace libyuv { 23f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangextern "C" { 24f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#endif 25f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 26f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// Convert camera sample to ARGB with cropping, rotation and vertical flip. 27f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// src_width is used for source stride computation 28f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// src_height is used to compute location of planes, and indicate inversion 29f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// sample_size is measured in bytes and is the size of the frame. 30f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// With MJPEG it is the compressed size of the frame. 31f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu KuangLIBYUV_API 32b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchardint ConvertToARGB(const uint8* sample, 33b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard size_t sample_size, 34b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard uint8* crop_argb, 35b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int argb_stride, 36b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int crop_x, 37b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int crop_y, 38b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int src_width, 39b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int src_height, 40b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int crop_width, 41b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int crop_height, 42f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang enum RotationMode rotation, 43f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint32 fourcc) { 44f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint32 format = CanonicalFourCC(fourcc); 45f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int aligned_src_width = (src_width + 1) & ~1; 46f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* src; 47f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* src_uv; 48f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int abs_src_height = (src_height < 0) ? -src_height : src_height; 49f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int inv_crop_height = (crop_height < 0) ? -crop_height : crop_height; 50f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int r = 0; 51f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 52f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // One pass rotation is available for some formats. For the rest, convert 5334040f466a2a1570d09e40bf2bc4b535181ef24dJorge E. Moreira // to ARGB (with optional vertical flipping) into a temporary ARGB buffer, 5434040f466a2a1570d09e40bf2bc4b535181ef24dJorge E. Moreira // and then rotate the ARGB to the final destination buffer. 55f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // For in-place conversion, if destination crop_argb is same as source sample, 56f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // also enable temporary buffer. 57b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard LIBYUV_BOOL need_buf = 58b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard (rotation && format != FOURCC_ARGB) || crop_argb == sample; 59f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8* dest_argb = crop_argb; 60f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dest_argb_stride = argb_stride; 61f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8* rotate_buffer = NULL; 62f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int abs_crop_height = (crop_height < 0) ? -crop_height : crop_height; 63f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 64b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard if (crop_argb == NULL || sample == NULL || src_width <= 0 || 65b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard crop_width <= 0 || src_height == 0 || crop_height == 0) { 66f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang return -1; 67f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 68f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (src_height < 0) { 69f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang inv_crop_height = -inv_crop_height; 70f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 71f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 72f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (need_buf) { 73f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int argb_size = crop_width * 4 * abs_crop_height; 74b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard rotate_buffer = (uint8*)malloc(argb_size); /* NOLINT */ 75f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (!rotate_buffer) { 76f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang return 1; // Out of memory runtime error. 77f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 78f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang crop_argb = rotate_buffer; 79f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang argb_stride = crop_width * 4; 80f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 81f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 82f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang switch (format) { 83f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // Single plane formats 84f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_YUY2: 85f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src = sample + (aligned_src_width * crop_y + crop_x) * 2; 86b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = YUY2ToARGB(src, aligned_src_width * 2, crop_argb, argb_stride, 87f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang crop_width, inv_crop_height); 88f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang break; 89f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_UYVY: 90f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src = sample + (aligned_src_width * crop_y + crop_x) * 2; 91b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = UYVYToARGB(src, aligned_src_width * 2, crop_argb, argb_stride, 92f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang crop_width, inv_crop_height); 93f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang break; 94f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_24BG: 95f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src = sample + (src_width * crop_y + crop_x) * 3; 96b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = RGB24ToARGB(src, src_width * 3, crop_argb, argb_stride, crop_width, 97b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard inv_crop_height); 98f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang break; 99f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_RAW: 100f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src = sample + (src_width * crop_y + crop_x) * 3; 101b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = RAWToARGB(src, src_width * 3, crop_argb, argb_stride, crop_width, 102b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard inv_crop_height); 103f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang break; 104f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_ARGB: 105b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard if (!need_buf && !rotation) { 10634040f466a2a1570d09e40bf2bc4b535181ef24dJorge E. Moreira src = sample + (src_width * crop_y + crop_x) * 4; 107b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = ARGBToARGB(src, src_width * 4, crop_argb, argb_stride, crop_width, 108b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard inv_crop_height); 10934040f466a2a1570d09e40bf2bc4b535181ef24dJorge E. Moreira } 110f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang break; 111f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_BGRA: 112f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src = sample + (src_width * crop_y + crop_x) * 4; 113b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = BGRAToARGB(src, src_width * 4, crop_argb, argb_stride, crop_width, 114b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard inv_crop_height); 115f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang break; 116f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_ABGR: 117f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src = sample + (src_width * crop_y + crop_x) * 4; 118b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = ABGRToARGB(src, src_width * 4, crop_argb, argb_stride, crop_width, 119b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard inv_crop_height); 120f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang break; 121f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_RGBA: 122f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src = sample + (src_width * crop_y + crop_x) * 4; 123b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = RGBAToARGB(src, src_width * 4, crop_argb, argb_stride, crop_width, 124b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard inv_crop_height); 125f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang break; 126f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_RGBP: 127f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src = sample + (src_width * crop_y + crop_x) * 2; 128b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = RGB565ToARGB(src, src_width * 2, crop_argb, argb_stride, crop_width, 129b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard inv_crop_height); 130f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang break; 131f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_RGBO: 132f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src = sample + (src_width * crop_y + crop_x) * 2; 133b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = ARGB1555ToARGB(src, src_width * 2, crop_argb, argb_stride, crop_width, 134b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard inv_crop_height); 135f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang break; 136f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_R444: 137f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src = sample + (src_width * crop_y + crop_x) * 2; 138b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = ARGB4444ToARGB(src, src_width * 2, crop_argb, argb_stride, crop_width, 139b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard inv_crop_height); 140f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang break; 141f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_I400: 142f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src = sample + src_width * crop_y + crop_x; 143b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = I400ToARGB(src, src_width, crop_argb, argb_stride, crop_width, 144b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard inv_crop_height); 145f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang break; 146f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 147f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // Biplanar formats 148f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_NV12: 149f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src = sample + (src_width * crop_y + crop_x); 150f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_uv = sample + aligned_src_width * (src_height + crop_y / 2) + crop_x; 151b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = NV12ToARGB(src, src_width, src_uv, aligned_src_width, crop_argb, 152b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard argb_stride, crop_width, inv_crop_height); 153f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang break; 154f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_NV21: 155f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src = sample + (src_width * crop_y + crop_x); 156f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_uv = sample + aligned_src_width * (src_height + crop_y / 2) + crop_x; 157f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // Call NV12 but with u and v parameters swapped. 158b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = NV21ToARGB(src, src_width, src_uv, aligned_src_width, crop_argb, 159b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard argb_stride, crop_width, inv_crop_height); 160f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang break; 161f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_M420: 162f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src = sample + (src_width * crop_y) * 12 / 8 + crop_x; 163b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = M420ToARGB(src, src_width, crop_argb, argb_stride, crop_width, 164b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard inv_crop_height); 165f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang break; 166f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // Triplanar formats 167f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_I420: 168f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_YV12: { 169f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* src_y = sample + (src_width * crop_y + crop_x); 170f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* src_u; 171f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* src_v; 172f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int halfwidth = (src_width + 1) / 2; 173f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int halfheight = (abs_src_height + 1) / 2; 174f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (format == FOURCC_YV12) { 175f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_v = sample + src_width * abs_src_height + 176b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard (halfwidth * crop_y + crop_x) / 2; 177f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_u = sample + src_width * abs_src_height + 178b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard halfwidth * (halfheight + crop_y / 2) + crop_x / 2; 179f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } else { 180f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_u = sample + src_width * abs_src_height + 181b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard (halfwidth * crop_y + crop_x) / 2; 182f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_v = sample + src_width * abs_src_height + 183b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard halfwidth * (halfheight + crop_y / 2) + crop_x / 2; 184f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 185b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = I420ToARGB(src_y, src_width, src_u, halfwidth, src_v, halfwidth, 186b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard crop_argb, argb_stride, crop_width, inv_crop_height); 187f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang break; 188f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 189f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 190f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_J420: { 191f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* src_y = sample + (src_width * crop_y + crop_x); 192f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* src_u; 193f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* src_v; 194f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int halfwidth = (src_width + 1) / 2; 195f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int halfheight = (abs_src_height + 1) / 2; 196f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_u = sample + src_width * abs_src_height + 197b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard (halfwidth * crop_y + crop_x) / 2; 198f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_v = sample + src_width * abs_src_height + 199b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard halfwidth * (halfheight + crop_y / 2) + crop_x / 2; 200b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = J420ToARGB(src_y, src_width, src_u, halfwidth, src_v, halfwidth, 201b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard crop_argb, argb_stride, crop_width, inv_crop_height); 202f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang break; 203f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 204f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 205f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_I422: 206f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_YV16: { 207f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* src_y = sample + src_width * crop_y + crop_x; 208f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* src_u; 209f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* src_v; 210f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int halfwidth = (src_width + 1) / 2; 211f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (format == FOURCC_YV16) { 212b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard src_v = sample + src_width * abs_src_height + halfwidth * crop_y + 213b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard crop_x / 2; 214f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_u = sample + src_width * abs_src_height + 215b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard halfwidth * (abs_src_height + crop_y) + crop_x / 2; 216f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } else { 217b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard src_u = sample + src_width * abs_src_height + halfwidth * crop_y + 218b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard crop_x / 2; 219f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_v = sample + src_width * abs_src_height + 220b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard halfwidth * (abs_src_height + crop_y) + crop_x / 2; 221f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 222b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = I422ToARGB(src_y, src_width, src_u, halfwidth, src_v, halfwidth, 223b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard crop_argb, argb_stride, crop_width, inv_crop_height); 224f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang break; 225f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 226f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_I444: 227f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_YV24: { 228f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* src_y = sample + src_width * crop_y + crop_x; 229f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* src_u; 230f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* src_v; 231f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (format == FOURCC_YV24) { 232f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_v = sample + src_width * (abs_src_height + crop_y) + crop_x; 233f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_u = sample + src_width * (abs_src_height * 2 + crop_y) + crop_x; 234f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } else { 235f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_u = sample + src_width * (abs_src_height + crop_y) + crop_x; 236f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_v = sample + src_width * (abs_src_height * 2 + crop_y) + crop_x; 237f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 238b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = I444ToARGB(src_y, src_width, src_u, src_width, src_v, src_width, 239b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard crop_argb, argb_stride, crop_width, inv_crop_height); 240f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang break; 241f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 242f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#ifdef HAVE_JPEG 243f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang case FOURCC_MJPG: 244b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = MJPGToARGB(sample, sample_size, crop_argb, argb_stride, src_width, 245b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard abs_src_height, crop_width, inv_crop_height); 246f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang break; 247f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#endif 248f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang default: 249f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang r = -1; // unknown fourcc - return failure code. 250f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 251f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 252f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (need_buf) { 253f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (!r) { 254b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = ARGBRotate(crop_argb, argb_stride, dest_argb, dest_argb_stride, 255f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang crop_width, abs_crop_height, rotation); 256f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 257f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang free(rotate_buffer); 25834040f466a2a1570d09e40bf2bc4b535181ef24dJorge E. Moreira } else if (rotation) { 25934040f466a2a1570d09e40bf2bc4b535181ef24dJorge E. Moreira src = sample + (src_width * crop_y + crop_x) * 4; 260b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = ARGBRotate(src, src_width * 4, crop_argb, argb_stride, crop_width, 261b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard inv_crop_height, rotation); 262f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 263f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 264f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang return r; 265f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 266f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 267f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#ifdef __cplusplus 268f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} // extern "C" 269f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} // namespace libyuv 270f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#endif 271