libyuv/source/row_common.cc

2685 lines
114 KiB
C++

/*
* Copyright 2011 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "libyuv/row.h"
#include <string.h> // For memcpy and memset.
#include "libyuv/basic_types.h"
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
// llvm x86 is poor at ternary operator, so use branchless min/max.
#define USE_BRANCHLESS 1
#if USE_BRANCHLESS
static __inline int32 clamp0(int32 v) {
return ((-(v) >> 31) & (v));
}
static __inline int32 clamp255(int32 v) {
return (((255 - (v)) >> 31) | (v)) & 255;
}
static __inline uint32 Clamp(int32 val) {
int v = clamp0(val);
return static_cast<uint32>(clamp255(v));
}
static __inline uint32 Abs(int32 v) {
int m = v >> 31;
return (v + m) ^ m;
}
#else // USE_BRANCHLESS
static __inline int32 clamp0(int32 v) {
return (v < 0) ? 0 : v;
}
static __inline int32 clamp255(int32 v) {
return (v > 255) ? 255 : v;
}
static __inline uint32 Clamp(int32 val) {
int v = clamp0(val);
return static_cast<uint32>(clamp255(v));
}
static __inline uint32 Abs(int32 v) {
return (v < 0) ? -v : v;
}
#endif // USE_BRANCHLESS
// floating point reciprocal.
extern const float kRecipTable[4097] = {
0.f, 65536.f, 32768., 21845.333984f, 16384.000000f, 13107.200195f,
10922.666992f, 9362.286133f, 8192.000000f, 7281.777832f, 6553.600098f,
5957.818359f, 5461.333496f, 5041.230957f, 4681.143066f, 4369.066895f,
4096.000000f, 3855.058838f, 3640.888916f, 3449.263184f, 3276.800049f,
3120.761963f, 2978.909180f, 2849.391357f, 2730.666748f, 2621.439941f,
2520.615479f, 2427.259277f, 2340.571533f, 2259.862061f, 2184.533447f,
2114.064453f, 2048.000000f, 1985.939453f, 1927.529419f, 1872.457153f,
1820.444458f, 1771.243286f, 1724.631592f, 1680.410278f, 1638.400024f,
1598.438965f, 1560.380981f, 1524.093018f, 1489.454590f, 1456.355591f,
1424.695679f, 1394.382935f, 1365.333374f, 1337.469360f, 1310.719971f,
1285.019653f, 1260.307739f, 1236.528320f, 1213.629639f, 1191.563599f,
1170.285767f, 1149.754395f, 1129.931030f, 1110.779663f, 1092.266724f,
1074.360596f, 1057.032227f, 1040.254028f, 1024.000000f, 1008.246155f,
992.969727f, 978.149231f, 963.764709f, 949.797119f, 936.228577f, 923.042236f,
910.222229f, 897.753418f, 885.621643f, 873.813354f, 862.315796f, 851.116882f,
840.205139f, 829.569641f, 819.200012f, 809.086426f, 799.219482f, 789.590332f,
780.190491f, 771.011780f, 762.046509f, 753.287354f, 744.727295f, 736.359558f,
728.177795f, 720.175842f, 712.347839f, 704.688171f, 697.191467f, 689.852661f,
682.666687f, 675.628845f, 668.734680f, 661.979797f, 655.359985f, 648.871277f,
642.509827f, 636.271851f, 630.153870f, 624.152405f, 618.264160f, 612.485962f,
606.814819f, 601.247681f, 595.781799f, 590.414429f, 585.142883f, 579.964600f,
574.877197f, 569.878235f, 564.965515f, 560.136780f, 555.389832f, 550.722717f,
546.133362f, 541.619812f, 537.180298f, 532.812988f, 528.516113f, 524.288025f,
520.127014f, 516.031494f, 512.000000f, 508.031006f, 504.123077f, 500.274811f,
496.484863f, 492.751892f, 489.074615f, 485.451843f, 481.882355f, 478.364960f,
474.898560f, 471.482025f, 468.114288f, 464.794312f, 461.521118f, 458.293701f,
455.111115f, 451.972412f, 448.876709f, 445.823120f, 442.810822f, 439.838928f,
436.906677f, 434.013245f, 431.157898f, 428.339874f, 425.558441f, 422.812897f,
420.102570f, 417.426758f, 414.784821f, 412.176086f, 409.600006f, 407.055908f,
404.543213f, 402.061340f, 399.609741f, 397.187866f, 394.795166f, 392.431152f,
390.095245f, 387.786987f, 385.505890f, 383.251465f, 381.023254f, 378.820801f,
376.643677f, 374.491425f, 372.363647f, 370.259888f, 368.179779f, 366.122894f,
364.088898f, 362.077362f, 360.087921f, 358.120209f, 356.173920f, 354.248657f,
352.344086f, 350.459900f, 348.595734f, 346.751312f, 344.926331f, 343.120422f,
341.333344f, 339.564758f, 337.814423f, 336.082062f, 334.367340f, 332.670044f,
330.989899f, 329.326630f, 327.679993f, 326.049744f, 324.435638f, 322.837433f,
321.254913f, 319.687805f, 318.135925f, 316.599030f, 315.076935f, 313.569366f,
312.076202f, 310.597168f, 309.132080f, 307.680756f, 306.242981f, 304.818604f,
303.407410f, 302.009216f, 300.623840f, 299.251129f, 297.890900f, 296.542999f,
295.207214f, 293.883423f, 292.571442f, 291.271118f, 289.982300f, 288.704834f,
287.438599f, 286.183411f, 284.939117f, 283.705627f, 282.482758f, 281.270386f,
280.068390f, 278.876587f, 277.694916f, 276.523193f, 275.361359f, 274.209198f,
273.066681f, 271.933624f, 270.809906f, 269.695465f, 268.590149f, 267.493866f,
266.406494f, 265.327942f, 264.258057f, 263.196777f, 262.144012f, 261.099609f,
260.063507f, 259.035583f, 258.015747f, 257.003937f, 256.000000f, 255.003891f,
254.015503f, 253.034744f, 252.061539f, 251.095779f, 250.137405f, 249.186310f,
248.242432f, 247.305664f, 246.375946f, 245.453186f, 244.537308f, 243.628250f,
242.725922f, 241.830261f, 240.941177f, 240.058609f, 239.182480f, 238.312729f,
237.449280f, 236.592056f, 235.741013f, 234.896057f, 234.057144f, 233.224197f,
232.397156f, 231.575974f, 230.760559f, 229.950882f, 229.146851f, 228.348434f,
227.555557f, 226.768173f, 225.986206f, 225.209625f, 224.438354f, 223.672348f,
222.911560f, 222.155930f, 221.405411f, 220.659927f, 219.919464f, 219.183945f,
218.453339f, 217.727570f, 217.006622f, 216.290436f, 215.578949f, 214.872131f,
214.169937f, 213.472305f, 212.779221f, 212.090622f, 211.406448f, 210.726685f,
210.051285f, 209.380188f, 208.713379f, 208.050797f, 207.392410f, 206.738174f,
206.088043f, 205.442001f, 204.800003f, 204.161987f, 203.527954f, 202.897827f,
202.271606f, 201.649231f, 201.030670f, 200.415909f, 199.804871f, 199.197571f,
198.593933f, 197.993958f, 197.397583f, 196.804810f, 196.215576f, 195.629852f,
195.047623f, 194.468842f, 193.893494f, 193.321533f, 192.752945f, 192.187683f,
191.625732f, 191.067062f, 190.511627f, 189.959427f, 189.410400f, 188.864548f,
188.321838f, 187.782242f, 187.245712f, 186.712250f, 186.181824f, 185.654388f,
185.129944f, 184.608444f, 184.089890f, 183.574234f, 183.061447f, 182.551529f,
182.044449f, 181.540161f, 181.038681f, 180.539948f, 180.043961f, 179.550690f,
179.060104f, 178.572205f, 178.086960f, 177.604340f, 177.124329f, 176.646896f,
176.172043f, 175.699738f, 175.229950f, 174.762665f, 174.297867f, 173.835541f,
173.375656f, 172.918213f, 172.463165f, 172.010498f, 171.560211f, 171.112274f,
170.666672f, 170.223373f, 169.782379f, 169.343674f, 168.907211f, 168.473007f,
168.041031f, 167.611252f, 167.183670f, 166.758270f, 166.335022f, 165.913925f,
165.494949f, 165.078079f, 164.663315f, 164.250626f, 163.839996f, 163.431427f,
163.024872f, 162.620346f, 162.217819f, 161.817291f, 161.418716f, 161.022110f,
160.627457f, 160.234726f, 159.843903f, 159.454987f, 159.067963f, 158.682816f,
158.299515f, 157.918076f, 157.538467f, 157.160675f, 156.784683f, 156.410507f,
156.038101f, 155.667465f, 155.298584f, 154.931442f, 154.566040f, 154.202347f,
153.840378f, 153.480087f, 153.121490f, 152.764572f, 152.409302f, 152.055679f,
151.703705f, 151.353348f, 151.004608f, 150.657471f, 150.311920f, 149.967957f,
149.625565f, 149.284744f, 148.945450f, 148.607712f, 148.271500f, 147.936798f,
147.603607f, 147.271912f, 146.941711f, 146.612976f, 146.285721f, 145.959915f,
145.635559f, 145.312637f, 144.991150f, 144.671082f, 144.352417f, 144.035172f,
143.719299f, 143.404816f, 143.091705f, 142.779953f, 142.469559f, 142.160522f,
141.852814f, 141.546432f, 141.241379f, 140.937637f, 140.635193f, 140.334045f,
140.034195f, 139.735611f, 139.438293f, 139.142258f, 138.847458f, 138.553909f,
138.261597f, 137.970520f, 137.680679f, 137.392029f, 137.104599f, 136.818375f,
136.533340f, 136.249481f, 135.966812f, 135.685303f, 135.404953f, 135.125778f,
134.847733f, 134.570847f, 134.295074f, 134.020447f, 133.746933f, 133.474548f,
133.203247f, 132.933060f, 132.663971f, 132.395966f, 132.129028f, 131.863174f,
131.598389f, 131.334671f, 131.072006f, 130.810379f, 130.549805f, 130.290253f,
130.031754f, 129.774261f, 129.517792f, 129.262329f, 129.007874f, 128.754425f,
128.501968f, 128.250488f, 128.000000f, 127.750488f, 127.501945f, 127.254372f,
127.007751f, 126.762093f, 126.517372f, 126.273605f, 126.030769f, 125.788864f,
125.547890f, 125.307838f, 125.068703f, 124.830475f, 124.593155f, 124.356735f,
124.121216f, 123.886581f, 123.652832f, 123.419960f, 123.187973f, 122.956848f,
122.726593f, 122.497200f, 122.268654f, 122.040970f, 121.814125f, 121.588127f,
121.362961f, 121.138634f, 120.915131f, 120.692451f, 120.470589f, 120.249542f,
120.029305f, 119.809875f, 119.591240f, 119.373405f, 119.156364f, 118.940109f,
118.724640f, 118.509949f, 118.296028f, 118.082886f, 117.870506f, 117.658890f,
117.448029f, 117.237923f, 117.028572f, 116.819962f, 116.612099f, 116.404976f,
116.198578f, 115.992920f, 115.787987f, 115.583771f, 115.380280f, 115.177505f,
114.975441f, 114.774078f, 114.573425f, 114.373474f, 114.174217f, 113.975655f,
113.777779f, 113.580589f, 113.384087f, 113.188255f, 112.993103f, 112.798622f,
112.604813f, 112.411667f, 112.219177f, 112.027351f, 111.836174f, 111.645653f,
111.455780f, 111.266556f, 111.077965f, 110.890015f, 110.702705f, 110.516022f,
110.329964f, 110.144539f, 109.959732f, 109.775543f, 109.591972f, 109.409012f,
109.226669f, 109.044922f, 108.863785f, 108.683250f, 108.503311f, 108.323967f,
108.145218f, 107.967049f, 107.789474f, 107.612480f, 107.436066f, 107.260231f,
107.084969f, 106.910278f, 106.736153f, 106.562599f, 106.389610f, 106.217178f,
106.045311f, 105.873993f, 105.703224f, 105.533012f, 105.363342f, 105.194221f,
105.025642f, 104.857597f, 104.690094f, 104.523125f, 104.356689f, 104.190781f,
104.025398f, 103.860542f, 103.696205f, 103.532387f, 103.369087f, 103.206299f,
103.044022f, 102.882263f, 102.721001f, 102.560249f, 102.400002f, 102.240250f,
102.080994f, 101.922241f, 101.763977f, 101.606201f, 101.448914f, 101.292114f,
101.135803f, 100.979973f, 100.824615f, 100.669739f, 100.515335f, 100.361412f,
100.207954f, 100.054962f, 99.902435f, 99.750381f, 99.598785f, 99.447647f,
99.296967f, 99.146744f, 98.996979f, 98.847664f, 98.698792f, 98.550377f,
98.402405f, 98.254875f, 98.107788f, 97.961136f, 97.814926f, 97.669151f,
97.523811f, 97.378899f, 97.234421f, 97.090370f, 96.946747f, 96.803543f,
96.660767f, 96.518410f, 96.376472f, 96.234947f, 96.093842f, 95.953148f,
95.812866f, 95.672989f, 95.533531f, 95.394470f, 95.255814f, 95.117561f,
94.979713f, 94.842255f, 94.705200f, 94.568542f, 94.432274f, 94.296402f,
94.160919f, 94.025826f, 93.891121f, 93.756798f, 93.622856f, 93.489304f,
93.356125f, 93.223328f, 93.090912f, 92.958862f, 92.827194f, 92.695900f,
92.564972f, 92.434418f, 92.304222f, 92.174400f, 92.044945f, 91.915848f,
91.787117f, 91.658745f, 91.530724f, 91.403069f, 91.275764f, 91.148819f,
91.022224f, 90.895981f, 90.770081f, 90.644539f, 90.519341f, 90.394485f,
90.269974f, 90.145805f, 90.021980f, 89.898491f, 89.775345f, 89.652534f,
89.530052f, 89.407913f, 89.286102f, 89.164627f, 89.043480f, 88.922661f,
88.802170f, 88.681999f, 88.562164f, 88.442642f, 88.323448f, 88.204575f,
88.086021f, 87.967789f, 87.849869f, 87.732262f, 87.614975f, 87.498001f,
87.381332f, 87.264977f, 87.148933f, 87.033203f, 86.917770f, 86.802650f,
86.687828f, 86.573318f, 86.459106f, 86.345192f, 86.231583f, 86.118263f,
86.005249f, 85.892532f, 85.780106f, 85.667976f, 85.556137f, 85.444588f,
85.333336f, 85.222366f, 85.111687f, 85.001297f, 84.891190f, 84.781372f,
84.671837f, 84.562584f, 84.453606f, 84.344917f, 84.236504f, 84.128372f,
84.020515f, 83.912933f, 83.805626f, 83.698593f, 83.591835f, 83.485352f,
83.379135f, 83.273186f, 83.167511f, 83.062103f, 82.956963f, 82.852089f,
82.747475f, 82.643127f, 82.539040f, 82.435219f, 82.331657f, 82.228355f,
82.125313f, 82.022530f, 81.919998f, 81.817726f, 81.715714f, 81.613945f,
81.512436f, 81.411179f, 81.310173f, 81.209419f, 81.108910f, 81.008652f,
80.908646f, 80.808876f, 80.709358f, 80.610085f, 80.511055f, 80.412270f,
80.313728f, 80.215424f, 80.117363f, 80.019539f, 79.921951f, 79.824608f,
79.727493f, 79.630623f, 79.533981f, 79.437576f, 79.341408f, 79.245468f,
79.149757f, 79.054283f, 78.959038f, 78.864021f, 78.769234f, 78.674667f,
78.580338f, 78.486229f, 78.392342f, 78.298683f, 78.205254f, 78.112038f,
78.019051f, 77.926277f, 77.833733f, 77.741402f, 77.649292f, 77.557396f,
77.465721f, 77.374260f, 77.283020f, 77.191994f, 77.101173f, 77.010574f,
76.920189f, 76.830009f, 76.740044f, 76.650291f, 76.560745f, 76.471413f,
76.382286f, 76.293365f, 76.204651f, 76.116142f, 76.027840f, 75.939743f,
75.851852f, 75.764160f, 75.676674f, 75.589386f, 75.502304f, 75.415421f,
75.328735f, 75.242249f, 75.155960f, 75.069878f, 74.983978f, 74.898285f,
74.812782f, 74.727478f, 74.642372f, 74.557449f, 74.472725f, 74.388199f,
74.303856f, 74.219704f, 74.135750f, 74.051979f, 73.968399f, 73.885002f,
73.801804f, 73.718788f, 73.635956f, 73.553314f, 73.470856f, 73.388580f,
73.306488f, 73.224579f, 73.142860f, 73.061317f, 72.979958f, 72.898773f,
72.817780f, 72.736961f, 72.656319f, 72.575859f, 72.495575f, 72.415466f,
72.335541f, 72.255791f, 72.176208f, 72.096809f, 72.017586f, 71.938530f,
71.859650f, 71.780945f, 71.702408f, 71.624046f, 71.545853f, 71.467827f,
71.389977f, 71.312294f, 71.234779f, 71.157440f, 71.080261f, 71.003250f,
70.926407f, 70.849731f, 70.773216f, 70.696869f, 70.620689f, 70.544670f,
70.468819f, 70.393127f, 70.317596f, 70.242226f, 70.167023f, 70.091980f,
70.017097f, 69.942368f, 69.867805f, 69.793396f, 69.719147f, 69.645058f,
69.571129f, 69.497353f, 69.423729f, 69.350266f, 69.276955f, 69.203804f,
69.130798f, 69.057953f, 68.985260f, 68.912720f, 68.840340f, 68.768097f,
68.696014f, 68.624084f, 68.552299f, 68.480667f, 68.409187f, 68.337852f,
68.266670f, 68.195633f, 68.124741f, 68.054001f, 67.983406f, 67.912956f,
67.842651f, 67.772491f, 67.702477f, 67.632614f, 67.562889f, 67.493309f,
67.423866f, 67.354576f, 67.285423f, 67.216408f, 67.147537f, 67.078812f,
67.010223f, 66.941780f, 66.873466f, 66.805298f, 66.737274f, 66.669380f,
66.601624f, 66.534012f, 66.466530f, 66.399193f, 66.331985f, 66.264915f,
66.197983f, 66.131180f, 66.064514f, 65.997986f, 65.931587f, 65.865326f,
65.799194f, 65.733200f, 65.667336f, 65.601601f, 65.536003f, 65.470528f,
65.405190f, 65.339981f, 65.274902f, 65.209953f, 65.145126f, 65.080437f,
65.015877f, 64.951439f, 64.887131f, 64.822945f, 64.758896f, 64.694969f,
64.631165f, 64.567490f, 64.503937f, 64.440514f, 64.377213f, 64.314034f,
64.250984f, 64.188049f, 64.125244f, 64.062561f, 64.000000f, 63.937561f,
63.875244f, 63.813049f, 63.750973f, 63.689018f, 63.627186f, 63.565472f,
63.503876f, 63.442402f, 63.381046f, 63.319805f, 63.258686f, 63.197685f,
63.136803f, 63.076035f, 63.015385f, 62.954849f, 62.894432f, 62.834133f,
62.773945f, 62.713875f, 62.653919f, 62.594078f, 62.534351f, 62.474739f,
62.415237f, 62.355850f, 62.296577f, 62.237415f, 62.178368f, 62.119431f,
62.060608f, 62.001892f, 61.943291f, 61.884796f, 61.826416f, 61.768143f,
61.709980f, 61.651928f, 61.593987f, 61.536152f, 61.478424f, 61.420807f,
61.363297f, 61.305893f, 61.248600f, 61.191410f, 61.134327f, 61.077354f,
61.020485f, 60.963722f, 60.907063f, 60.850510f, 60.794064f, 60.737720f,
60.681480f, 60.625347f, 60.569317f, 60.513390f, 60.457565f, 60.401844f,
60.346226f, 60.290707f, 60.235294f, 60.179981f, 60.124771f, 60.069660f,
60.014652f, 59.959743f, 59.904938f, 59.850227f, 59.795620f, 59.741112f,
59.686703f, 59.632393f, 59.578182f, 59.524071f, 59.470055f, 59.416138f,
59.362320f, 59.308598f, 59.254974f, 59.201447f, 59.148014f, 59.094681f,
59.041443f, 58.988300f, 58.935253f, 58.882301f, 58.829445f, 58.776680f,
58.724014f, 58.671440f, 58.618961f, 58.566578f, 58.514286f, 58.462086f,
58.409981f, 58.357971f, 58.306049f, 58.254223f, 58.202488f, 58.150845f,
58.099289f, 58.047829f, 57.996460f, 57.945183f, 57.893993f, 57.842896f,
57.791885f, 57.740971f, 57.690140f, 57.639400f, 57.588753f, 57.538193f,
57.487720f, 57.437336f, 57.387039f, 57.336834f, 57.286713f, 57.236683f,
57.186737f, 57.136879f, 57.087109f, 57.037422f, 56.987827f, 56.938316f,
56.888889f, 56.839550f, 56.790295f, 56.741127f, 56.692043f, 56.643044f,
56.594128f, 56.545300f, 56.496552f, 56.447891f, 56.399311f, 56.350819f,
56.302406f, 56.254078f, 56.205833f, 56.157669f, 56.109589f, 56.061592f,
56.013676f, 55.965839f, 55.918087f, 55.870419f, 55.822826f, 55.775318f,
55.727890f, 55.680542f, 55.633278f, 55.586090f, 55.538982f, 55.491955f,
55.445007f, 55.398140f, 55.351353f, 55.304642f, 55.258011f, 55.211456f,
55.164982f, 55.118587f, 55.072269f, 55.026028f, 54.979866f, 54.933781f,
54.887772f, 54.841843f, 54.795986f, 54.750210f, 54.704506f, 54.658882f,
54.613335f, 54.567860f, 54.522461f, 54.477142f, 54.431892f, 54.386723f,
54.341625f, 54.296604f, 54.251656f, 54.206783f, 54.161983f, 54.117260f,
54.072609f, 54.028030f, 53.983524f, 53.939095f, 53.894737f, 53.850452f,
53.806240f, 53.762100f, 53.718033f, 53.674038f, 53.630116f, 53.586262f,
53.542484f, 53.498775f, 53.455139f, 53.411572f, 53.368076f, 53.324654f,
53.281300f, 53.238018f, 53.194805f, 53.151661f, 53.108589f, 53.065586f,
53.022655f, 52.979790f, 52.936996f, 52.894268f, 52.851612f, 52.809025f,
52.766506f, 52.724056f, 52.681671f, 52.639359f, 52.597111f, 52.554932f,
52.512821f, 52.470776f, 52.428799f, 52.386890f, 52.345047f, 52.303272f,
52.261562f, 52.219921f, 52.178345f, 52.136833f, 52.095390f, 52.054012f,
52.012699f, 51.971451f, 51.930271f, 51.889153f, 51.848103f, 51.807114f,
51.766193f, 51.725334f, 51.684544f, 51.643814f, 51.603149f, 51.562550f,
51.522011f, 51.481541f, 51.441132f, 51.400784f, 51.360500f, 51.320282f,
51.280125f, 51.240032f, 51.200001f, 51.160030f, 51.120125f, 51.080280f,
51.040497f, 51.000778f, 50.961121f, 50.921524f, 50.881989f, 50.842514f,
50.803101f, 50.763748f, 50.724457f, 50.685226f, 50.646057f, 50.606949f,
50.567902f, 50.528912f, 50.489986f, 50.451115f, 50.412308f, 50.373558f,
50.334869f, 50.296238f, 50.257668f, 50.219158f, 50.180706f, 50.142311f,
50.103977f, 50.065701f, 50.027481f, 49.989323f, 49.951218f, 49.913177f,
49.875191f, 49.837261f, 49.799393f, 49.761578f, 49.723824f, 49.686127f,
49.648483f, 49.610901f, 49.573372f, 49.535904f, 49.498489f, 49.461132f,
49.423832f, 49.386585f, 49.349396f, 49.312263f, 49.275188f, 49.238167f,
49.201202f, 49.164291f, 49.127438f, 49.090637f, 49.053894f, 49.017204f,
48.980568f, 48.943989f, 48.907463f, 48.870991f, 48.834576f, 48.798214f,
48.761906f, 48.725651f, 48.689449f, 48.653305f, 48.617210f, 48.581173f,
48.545185f, 48.509251f, 48.473373f, 48.437546f, 48.401772f, 48.366051f,
48.330383f, 48.294769f, 48.259205f, 48.223694f, 48.188236f, 48.152828f,
48.117474f, 48.082172f, 48.046921f, 48.011723f, 47.976574f, 47.941479f,
47.906433f, 47.871441f, 47.836494f, 47.801605f, 47.766766f, 47.731976f,
47.697235f, 47.662544f, 47.627907f, 47.593319f, 47.558781f, 47.524292f,
47.489857f, 47.455467f, 47.421127f, 47.386841f, 47.352600f, 47.318413f,
47.284271f, 47.250179f, 47.216137f, 47.182144f, 47.148201f, 47.114307f,
47.080460f, 47.046661f, 47.012913f, 46.979210f, 46.945560f, 46.911953f,
46.878399f, 46.844891f, 46.811428f, 46.778015f, 46.744652f, 46.711334f,
46.678062f, 46.644840f, 46.611664f, 46.578537f, 46.545456f, 46.512421f,
46.479431f, 46.446491f, 46.413597f, 46.380749f, 46.347950f, 46.315193f,
46.282486f, 46.249825f, 46.217209f, 46.184635f, 46.152111f, 46.119633f,
46.087200f, 46.054813f, 46.022472f, 45.990177f, 45.957924f, 45.925716f,
45.893559f, 45.861443f, 45.829372f, 45.797344f, 45.765362f, 45.733425f,
45.701534f, 45.669685f, 45.637882f, 45.606125f, 45.574409f, 45.542740f,
45.511112f, 45.479527f, 45.447990f, 45.416492f, 45.385040f, 45.353634f,
45.322269f, 45.290947f, 45.259670f, 45.228432f, 45.197243f, 45.166092f,
45.134987f, 45.103924f, 45.072903f, 45.041924f, 45.010990f, 44.980095f,
44.949245f, 44.918438f, 44.887672f, 44.856949f, 44.826267f, 44.795624f,
44.765026f, 44.734470f, 44.703957f, 44.673485f, 44.643051f, 44.612663f,
44.582314f, 44.552006f, 44.521740f, 44.491512f, 44.461330f, 44.431187f,
44.401085f, 44.371021f, 44.341000f, 44.311020f, 44.281082f, 44.251183f,
44.221321f, 44.191505f, 44.161724f, 44.131985f, 44.102287f, 44.072628f,
44.043011f, 44.013432f, 43.983894f, 43.954391f, 43.924934f, 43.895512f,
43.866131f, 43.836788f, 43.807487f, 43.778225f, 43.749001f, 43.719814f,
43.690666f, 43.661560f, 43.632488f, 43.603458f, 43.574467f, 43.545513f,
43.516602f, 43.487724f, 43.458885f, 43.430088f, 43.401325f, 43.372601f,
43.343914f, 43.315269f, 43.286659f, 43.258087f, 43.229553f, 43.201054f,
43.172596f, 43.144173f, 43.115791f, 43.087444f, 43.059132f, 43.030861f,
43.002625f, 42.974426f, 42.946266f, 42.918140f, 42.890053f, 42.862000f,
42.833988f, 42.806007f, 42.778069f, 42.750164f, 42.722294f, 42.694462f,
42.666668f, 42.638908f, 42.611183f, 42.583496f, 42.555843f, 42.528229f,
42.500648f, 42.473103f, 42.445595f, 42.418121f, 42.390686f, 42.363285f,
42.335918f, 42.308586f, 42.281292f, 42.254028f, 42.226803f, 42.199615f,
42.172459f, 42.145336f, 42.118252f, 42.091202f, 42.064186f, 42.037205f,
42.010258f, 41.983345f, 41.956467f, 41.929623f, 41.902813f, 41.876038f,
41.849297f, 41.822590f, 41.795918f, 41.769279f, 41.742676f, 41.716103f,
41.689568f, 41.663063f, 41.636593f, 41.610157f, 41.583755f, 41.557388f,
41.531052f, 41.504749f, 41.478481f, 41.452244f, 41.426044f, 41.399872f,
41.373737f, 41.347633f, 41.321564f, 41.295525f, 41.269520f, 41.243549f,
41.217609f, 41.191704f, 41.165829f, 41.139988f, 41.114178f, 41.088402f,
41.062656f, 41.036945f, 41.011265f, 40.985615f, 40.959999f, 40.934418f,
40.908863f, 40.883343f, 40.857857f, 40.832397f, 40.806973f, 40.781582f,
40.756218f, 40.730888f, 40.705589f, 40.680325f, 40.655087f, 40.629883f,
40.604710f, 40.579567f, 40.554455f, 40.529377f, 40.504326f, 40.479309f,
40.454323f, 40.429363f, 40.404438f, 40.379543f, 40.354679f, 40.329845f,
40.305042f, 40.280270f, 40.255527f, 40.230816f, 40.206135f, 40.181484f,
40.156864f, 40.132271f, 40.107712f, 40.083179f, 40.058681f, 40.034210f,
40.009769f, 39.985355f, 39.960976f, 39.936623f, 39.912304f, 39.888008f,
39.863747f, 39.839512f, 39.815311f, 39.791134f, 39.766991f, 39.742874f,
39.718788f, 39.694729f, 39.670704f, 39.646702f, 39.622734f, 39.598793f,
39.574879f, 39.550995f, 39.527142f, 39.503315f, 39.479519f, 39.455750f,
39.432011f, 39.408298f, 39.384617f, 39.360962f, 39.337334f, 39.313736f,
39.290169f, 39.266628f, 39.243114f, 39.219627f, 39.196171f, 39.172745f,
39.149342f, 39.125969f, 39.102627f, 39.079308f, 39.056019f, 39.032757f,
39.009525f, 38.986317f, 38.963139f, 38.939987f, 38.916866f, 38.893768f,
38.870701f, 38.847660f, 38.824646f, 38.801659f, 38.778698f, 38.755764f,
38.732861f, 38.709984f, 38.687130f, 38.664307f, 38.641510f, 38.618740f,
38.595997f, 38.573277f, 38.550587f, 38.527924f, 38.505287f, 38.482677f,
38.460094f, 38.437538f, 38.415005f, 38.392502f, 38.370022f, 38.347572f,
38.325146f, 38.302746f, 38.280373f, 38.258026f, 38.235706f, 38.213409f,
38.191143f, 38.168900f, 38.146683f, 38.124493f, 38.102325f, 38.080185f,
38.058071f, 38.035984f, 38.013920f, 37.991882f, 37.969872f, 37.947887f,
37.925926f, 37.903992f, 37.882080f, 37.860195f, 37.838337f, 37.816502f,
37.794693f, 37.772911f, 37.751152f, 37.729420f, 37.707710f, 37.686028f,
37.664368f, 37.642735f, 37.621124f, 37.599541f, 37.577980f, 37.556446f,
37.534939f, 37.513451f, 37.491989f, 37.470554f, 37.449142f, 37.427757f,
37.406391f, 37.385056f, 37.363739f, 37.342449f, 37.321186f, 37.299942f,
37.278725f, 37.257534f, 37.236362f, 37.215218f, 37.194099f, 37.173000f,
37.151928f, 37.130878f, 37.109852f, 37.088852f, 37.067875f, 37.046921f,
37.025990f, 37.005081f, 36.984200f, 36.963341f, 36.942501f, 36.921692f,
36.900902f, 36.880135f, 36.859394f, 36.838673f, 36.817978f, 36.797306f,
36.776657f, 36.756031f, 36.735428f, 36.714848f, 36.694290f, 36.673756f,
36.653244f, 36.632755f, 36.612289f, 36.591846f, 36.571430f, 36.551033f,
36.530659f, 36.510307f, 36.489979f, 36.469673f, 36.449387f, 36.429127f,
36.408890f, 36.388672f, 36.368481f, 36.348309f, 36.328159f, 36.308033f,
36.287930f, 36.267849f, 36.247787f, 36.227749f, 36.207733f, 36.187740f,
36.167770f, 36.147820f, 36.127895f, 36.107990f, 36.088104f, 36.068245f,
36.048405f, 36.028587f, 36.008793f, 35.989017f, 35.969265f, 35.949535f,
35.929825f, 35.910137f, 35.890472f, 35.870827f, 35.851204f, 35.831600f,
35.812023f, 35.792461f, 35.772926f, 35.753410f, 35.733913f, 35.714443f,
35.694988f, 35.675556f, 35.656147f, 35.636761f, 35.617390f, 35.598045f,
35.578720f, 35.559414f, 35.540131f, 35.520866f, 35.501625f, 35.482403f,
35.463203f, 35.444023f, 35.424866f, 35.405727f, 35.386608f, 35.367512f,
35.348434f, 35.329380f, 35.310345f, 35.291328f, 35.272335f, 35.253361f,
35.234409f, 35.215477f, 35.196564f, 35.177670f, 35.158798f, 35.139946f,
35.121113f, 35.102303f, 35.083511f, 35.064739f, 35.045990f, 35.027260f,
35.008549f, 34.989857f, 34.971184f, 34.952534f, 34.933903f, 34.915291f,
34.896698f, 34.878128f, 34.859573f, 34.841042f, 34.822529f, 34.804035f,
34.785564f, 34.767109f, 34.748676f, 34.730259f, 34.711864f, 34.693489f,
34.675133f, 34.656796f, 34.638477f, 34.620178f, 34.601902f, 34.583641f,
34.565399f, 34.547180f, 34.528976f, 34.510796f, 34.492630f, 34.474487f,
34.456360f, 34.438255f, 34.420170f, 34.402100f, 34.384048f, 34.366020f,
34.348007f, 34.330017f, 34.312042f, 34.294086f, 34.276150f, 34.258232f,
34.240334f, 34.222454f, 34.204594f, 34.186749f, 34.168926f, 34.151119f,
34.133335f, 34.115566f, 34.097816f, 34.080082f, 34.062370f, 34.044674f,
34.027000f, 34.009342f, 33.991703f, 33.974079f, 33.956478f, 33.938892f,
33.921326f, 33.903778f, 33.886246f, 33.868732f, 33.851238f, 33.833763f,
33.816307f, 33.798866f, 33.781445f, 33.764038f, 33.746655f, 33.729286f,
33.711933f, 33.694603f, 33.677288f, 33.659988f, 33.642712f, 33.625450f,
33.608204f, 33.590981f, 33.573769f, 33.556580f, 33.539406f, 33.522251f,
33.505112f, 33.487991f, 33.470890f, 33.453804f, 33.436733f, 33.419685f,
33.402649f, 33.385635f, 33.368637f, 33.351654f, 33.334690f, 33.317741f,
33.300812f, 33.283901f, 33.267006f, 33.250126f, 33.233265f, 33.216423f,
33.199596f, 33.182785f, 33.165993f, 33.149216f, 33.132458f, 33.115715f,
33.098991f, 33.082283f, 33.065590f, 33.048916f, 33.032257f, 33.015617f,
32.998993f, 32.982384f, 32.965794f, 32.949223f, 32.932663f, 32.916122f,
32.899597f, 32.883091f, 32.866600f, 32.850124f, 32.833668f, 32.817226f,
32.800800f, 32.784393f, 32.768002f, 32.751625f, 32.735264f, 32.718922f,
32.702595f, 32.686283f, 32.669991f, 32.653713f, 32.637451f, 32.621204f,
32.604977f, 32.588760f, 32.572563f, 32.556385f, 32.540218f, 32.524071f,
32.507938f, 32.491821f, 32.475719f, 32.459633f, 32.443565f, 32.427509f,
32.411472f, 32.395451f, 32.379448f, 32.363457f, 32.347485f, 32.331524f,
32.315582f, 32.299656f, 32.283745f, 32.267849f, 32.251968f, 32.236103f,
32.220257f, 32.204422f, 32.188606f, 32.172802f, 32.157017f, 32.141247f,
32.125492f, 32.109749f, 32.094025f, 32.078316f, 32.062622f, 32.046944f,
32.031281f, 32.015633f, 32.000000f, 31.984383f, 31.968781f, 31.953194f,
31.937622f, 31.922066f, 31.906525f, 31.890997f, 31.875486f, 31.859991f,
31.844509f, 31.829042f, 31.813593f, 31.798157f, 31.782736f, 31.767328f,
31.751938f, 31.736561f, 31.721201f, 31.705854f, 31.690523f, 31.675205f,
31.659903f, 31.644617f, 31.629343f, 31.614086f, 31.598843f, 31.583614f,
31.568401f, 31.553202f, 31.538017f, 31.522848f, 31.507692f, 31.492552f,
31.477425f, 31.462315f, 31.447216f, 31.432135f, 31.417067f, 31.402012f,
31.386972f, 31.371948f, 31.356937f, 31.341942f, 31.326960f, 31.311993f,
31.297039f, 31.282101f, 31.267176f, 31.252266f, 31.237370f, 31.222486f,
31.207619f, 31.192766f, 31.177925f, 31.163101f, 31.148289f, 31.133492f,
31.118708f, 31.103939f, 31.089184f, 31.074444f, 31.059715f, 31.045002f,
31.030304f, 31.015617f, 31.000946f, 30.986288f, 30.971645f, 30.957014f,
30.942398f, 30.927795f, 30.913208f, 30.898632f, 30.884071f, 30.869524f,
30.854990f, 30.840471f, 30.825964f, 30.811472f, 30.796993f, 30.782528f,
30.768076f, 30.753637f, 30.739212f, 30.724800f, 30.710403f, 30.696018f,
30.681648f, 30.667290f, 30.652946f, 30.638617f, 30.624300f, 30.609995f,
30.595705f, 30.581429f, 30.567163f, 30.552914f, 30.538677f, 30.524452f,
30.510242f, 30.496044f, 30.481861f, 30.467690f, 30.453531f, 30.439386f,
30.425255f, 30.411137f, 30.397032f, 30.382938f, 30.368860f, 30.354794f,
30.340740f, 30.326700f, 30.312674f, 30.298658f, 30.284658f, 30.270670f,
30.256695f, 30.242731f, 30.228783f, 30.214846f, 30.200922f, 30.187010f,
30.173113f, 30.159227f, 30.145353f, 30.131495f, 30.117647f, 30.103813f,
30.089991f, 30.076181f, 30.062386f, 30.048601f, 30.034830f, 30.021072f,
30.007326f, 29.993593f, 29.979872f, 29.966164f, 29.952469f, 29.938786f,
29.925114f, 29.911455f, 29.897810f, 29.884176f, 29.870556f, 29.856947f,
29.843351f, 29.829767f, 29.816196f, 29.802637f, 29.789091f, 29.775557f,
29.762035f, 29.748526f, 29.735027f, 29.721542f, 29.708069f, 29.694609f,
29.681160f, 29.667723f, 29.654299f, 29.640886f, 29.627487f, 29.614098f,
29.600723f, 29.587358f, 29.574007f, 29.560667f, 29.547340f, 29.534025f,
29.520721f, 29.507429f, 29.494150f, 29.480883f, 29.467627f, 29.454382f,
29.441151f, 29.427931f, 29.414722f, 29.401525f, 29.388340f, 29.375168f,
29.362007f, 29.348858f, 29.335720f, 29.322596f, 29.309481f, 29.296379f,
29.283289f, 29.270210f, 29.257143f, 29.244087f, 29.231043f, 29.218012f,
29.204990f, 29.191982f, 29.178986f, 29.165998f, 29.153025f, 29.140062f,
29.127111f, 29.114172f, 29.101244f, 29.088327f, 29.075422f, 29.062529f,
29.049644f, 29.036774f, 29.023914f, 29.011066f, 28.998230f, 28.985405f,
28.972591f, 28.959787f, 28.946997f, 28.934216f, 28.921448f, 28.908689f,
28.895943f, 28.883209f, 28.870485f, 28.857773f, 28.845070f, 28.832380f,
28.819700f, 28.807034f, 28.794376f, 28.781731f, 28.769096f, 28.756472f,
28.743860f, 28.731258f, 28.718668f, 28.706089f, 28.693520f, 28.680964f,
28.668417f, 28.655882f, 28.643356f, 28.630844f, 28.618341f, 28.605848f,
28.593369f, 28.580898f, 28.568439f, 28.555992f, 28.543554f, 28.531128f,
28.518711f, 28.506308f, 28.493914f, 28.481529f, 28.469158f, 28.456795f,
28.444445f, 28.432104f, 28.419775f, 28.407455f, 28.395147f, 28.382851f,
28.370564f, 28.358286f, 28.346022f, 28.333765f, 28.321522f, 28.309288f,
28.297064f, 28.284851f, 28.272650f, 28.260458f, 28.248276f, 28.236105f,
28.223946f, 28.211796f, 28.199656f, 28.187527f, 28.175409f, 28.163300f,
28.151203f, 28.139116f, 28.127039f, 28.114973f, 28.102917f, 28.090870f,
28.078835f, 28.066809f, 28.054794f, 28.042789f, 28.030796f, 28.018812f,
28.006838f, 27.994873f, 27.982920f, 27.970978f, 27.959044f, 27.947121f,
27.935209f, 27.923306f, 27.911413f, 27.899532f, 27.887659f, 27.875797f,
27.863945f, 27.852104f, 27.840271f, 27.828449f, 27.816639f, 27.804836f,
27.793045f, 27.781263f, 27.769491f, 27.757730f, 27.745977f, 27.734236f,
27.722504f, 27.710783f, 27.699070f, 27.687368f, 27.675676f, 27.663994f,
27.652321f, 27.640657f, 27.629005f, 27.617361f, 27.605728f, 27.594105f,
27.582491f, 27.570889f, 27.559294f, 27.547709f, 27.536135f, 27.524569f,
27.513014f, 27.501469f, 27.489933f, 27.478407f, 27.466890f, 27.455383f,
27.443886f, 27.432398f, 27.420921f, 27.409452f, 27.397993f, 27.386543f,
27.375105f, 27.363674f, 27.352253f, 27.340843f, 27.329441f, 27.318048f,
27.306667f, 27.295294f, 27.283930f, 27.272575f, 27.261230f, 27.249897f,
27.238571f, 27.227253f, 27.215946f, 27.204649f, 27.193361f, 27.182081f,
27.170813f, 27.159552f, 27.148302f, 27.137060f, 27.125828f, 27.114605f,
27.103392f, 27.092186f, 27.080992f, 27.069805f, 27.058630f, 27.047462f,
27.036304f, 27.025154f, 27.014015f, 27.002884f, 26.991762f, 26.980650f,
26.969547f, 26.958454f, 26.947369f, 26.936293f, 26.925226f, 26.914169f,
26.903120f, 26.892080f, 26.881050f, 26.870029f, 26.859016f, 26.848013f,
26.837019f, 26.826033f, 26.815058f, 26.804090f, 26.793131f, 26.782183f,
26.771242f, 26.760311f, 26.749388f, 26.738474f, 26.727570f, 26.716673f,
26.705786f, 26.694908f, 26.684038f, 26.673180f, 26.662327f, 26.651484f,
26.640650f, 26.629826f, 26.619009f, 26.608202f, 26.597403f, 26.586613f,
26.575830f, 26.565060f, 26.554295f, 26.543539f, 26.532793f, 26.522057f,
26.511328f, 26.500607f, 26.489895f, 26.479193f, 26.468498f, 26.457811f,
26.447134f, 26.436466f, 26.425806f, 26.415155f, 26.404512f, 26.393879f,
26.383253f, 26.372635f, 26.362028f, 26.351427f, 26.340836f, 26.330254f,
26.319679f, 26.309113f, 26.298555f, 26.288006f, 26.277466f, 26.266933f,
26.256411f, 26.245895f, 26.235388f, 26.224890f, 26.214399f, 26.203918f,
26.193445f, 26.182980f, 26.172523f, 26.162075f, 26.151636f, 26.141205f,
26.130781f, 26.120367f, 26.109961f, 26.099562f, 26.089172f, 26.078791f,
26.068417f, 26.058052f, 26.047695f, 26.037346f, 26.027006f, 26.016674f,
26.006350f, 25.996033f, 25.985725f, 25.975426f, 25.965136f, 25.954851f,
25.944576f, 25.934309f, 25.924051f, 25.913799f, 25.903557f, 25.893322f,
25.883097f, 25.872877f, 25.862667f, 25.852465f, 25.842272f, 25.832085f,
25.821907f, 25.811737f, 25.801575f, 25.791420f, 25.781275f, 25.771137f,
25.761005f, 25.750885f, 25.740770f, 25.730663f, 25.720566f, 25.710474f,
25.700392f, 25.690317f, 25.680250f, 25.670193f, 25.660141f, 25.650099f,
25.640062f, 25.630035f, 25.620016f, 25.610004f, 25.600000f, 25.590004f,
25.580015f, 25.570036f, 25.560062f, 25.550098f, 25.540140f, 25.530191f,
25.520248f, 25.510315f, 25.500389f, 25.490471f, 25.480560f, 25.470657f,
25.460762f, 25.450874f, 25.440994f, 25.431122f, 25.421257f, 25.411400f,
25.401550f, 25.391708f, 25.381874f, 25.372047f, 25.362228f, 25.352417f,
25.342613f, 25.332817f, 25.323029f, 25.313248f, 25.303474f, 25.293709f,
25.283951f, 25.274200f, 25.264456f, 25.254721f, 25.244993f, 25.235271f,
25.225557f, 25.215853f, 25.206154f, 25.196463f, 25.186779f, 25.177103f,
25.167435f, 25.157774f, 25.148119f, 25.138474f, 25.128834f, 25.119204f,
25.109579f, 25.099962f, 25.090353f, 25.080750f, 25.071156f, 25.061567f,
25.051989f, 25.042416f, 25.032850f, 25.023291f, 25.013741f, 25.004196f,
24.994661f, 24.985132f, 24.975609f, 24.966095f, 24.956589f, 24.947088f,
24.937595f, 24.928110f, 24.918631f, 24.909161f, 24.899696f, 24.890240f,
24.880789f, 24.871347f, 24.861912f, 24.852484f, 24.843063f, 24.833649f,
24.824242f, 24.814842f, 24.805450f, 24.796064f, 24.786686f, 24.777315f,
24.767952f, 24.758595f, 24.749245f, 24.739902f, 24.730566f, 24.721237f,
24.711916f, 24.702600f, 24.693293f, 24.683992f, 24.674698f, 24.665413f,
24.656132f, 24.646860f, 24.637594f, 24.628336f, 24.619083f, 24.609838f,
24.600601f, 24.591370f, 24.582146f, 24.572927f, 24.563719f, 24.554514f,
24.545319f, 24.536129f, 24.526947f, 24.517771f, 24.508602f, 24.499439f,
24.490284f, 24.481136f, 24.471994f, 24.462860f, 24.453732f, 24.444611f,
24.435495f, 24.426388f, 24.417288f, 24.408194f, 24.399107f, 24.390026f,
24.380953f, 24.371885f, 24.362825f, 24.353771f, 24.344725f, 24.335686f,
24.326653f, 24.317625f, 24.308605f, 24.299593f, 24.290586f, 24.281586f,
24.272593f, 24.263607f, 24.254625f, 24.245653f, 24.236687f, 24.227726f,
24.218773f, 24.209826f, 24.200886f, 24.191954f, 24.183025f, 24.174105f,
24.165192f, 24.156284f, 24.147385f, 24.138491f, 24.129602f, 24.120722f,
24.111847f, 24.102980f, 24.094118f, 24.085262f, 24.076414f, 24.067572f,
24.058737f, 24.049908f, 24.041086f, 24.032270f, 24.023460f, 24.014658f,
24.005861f, 23.997070f, 23.988287f, 23.979509f, 23.970739f, 23.961975f,
23.953217f, 23.944466f, 23.935720f, 23.926981f, 23.918247f, 23.909523f,
23.900803f, 23.892090f, 23.883383f, 23.874681f, 23.865988f, 23.857300f,
23.848618f, 23.839941f, 23.831272f, 23.822611f, 23.813953f, 23.805304f,
23.796659f, 23.788021f, 23.779390f, 23.770765f, 23.762146f, 23.753534f,
23.744928f, 23.736328f, 23.727734f, 23.719147f, 23.710564f, 23.701988f,
23.693420f, 23.684856f, 23.676300f, 23.667749f, 23.659206f, 23.650667f,
23.642136f, 23.633610f, 23.625090f, 23.616577f, 23.608068f, 23.599567f,
23.591072f, 23.582584f, 23.574100f, 23.565624f, 23.557154f, 23.548689f,
23.540230f, 23.531776f, 23.523331f, 23.514891f, 23.506456f, 23.498028f,
23.489605f, 23.481190f, 23.472780f, 23.464375f, 23.455976f, 23.447584f,
23.439199f, 23.430819f, 23.422445f, 23.414076f, 23.405714f, 23.397358f,
23.389008f, 23.380663f, 23.372326f, 23.363993f, 23.355667f, 23.347345f,
23.339031f, 23.330723f, 23.322420f, 23.314123f, 23.305832f, 23.297546f,
23.289268f, 23.280994f, 23.272728f, 23.264465f, 23.256210f, 23.247961f,
23.239716f, 23.231478f, 23.223246f, 23.215019f, 23.206799f, 23.198584f,
23.190374f, 23.182173f, 23.173975f, 23.165783f, 23.157597f, 23.149418f,
23.141243f, 23.133074f, 23.124912f, 23.116755f, 23.108604f, 23.100458f,
23.092318f, 23.084185f, 23.076056f, 23.067934f, 23.059816f, 23.051706f,
23.043600f, 23.035501f, 23.027407f, 23.019320f, 23.011236f, 23.003159f,
22.995089f, 22.987022f, 22.978962f, 22.970907f, 22.962858f, 22.954817f,
22.946779f, 22.938747f, 22.930721f, 22.922701f, 22.914686f, 22.906675f,
22.898672f, 22.890675f, 22.882681f, 22.874695f, 22.866713f, 22.858738f,
22.850767f, 22.842802f, 22.834843f, 22.826889f, 22.818941f, 22.810999f,
22.803062f, 22.795130f, 22.787205f, 22.779284f, 22.771370f, 22.763460f,
22.755556f, 22.747658f, 22.739763f, 22.731876f, 22.723995f, 22.716118f,
22.708246f, 22.700380f, 22.692520f, 22.684666f, 22.676817f, 22.668972f,
22.661135f, 22.653301f, 22.645473f, 22.637651f, 22.629835f, 22.622023f,
22.614216f, 22.606417f, 22.598621f, 22.590830f, 22.583046f, 22.575268f,
22.567493f, 22.559725f, 22.551962f, 22.544203f, 22.536451f, 22.528704f,
22.520962f, 22.513226f, 22.505495f, 22.497768f, 22.490047f, 22.482332f,
22.474623f, 22.466919f, 22.459219f, 22.451525f, 22.443836f, 22.436152f,
22.428474f, 22.420801f, 22.413134f, 22.405470f, 22.397812f, 22.390162f,
22.382513f, 22.374872f, 22.367235f, 22.359604f, 22.351978f, 22.344357f,
22.336742f, 22.329132f, 22.321526f, 22.313927f, 22.306332f, 22.298740f,
22.291157f, 22.283577f, 22.276003f, 22.268435f, 22.260870f, 22.253311f,
22.245756f, 22.238209f, 22.230665f, 22.223127f, 22.215593f, 22.208065f,
22.200542f, 22.193024f, 22.185511f, 22.178003f, 22.170500f, 22.163004f,
22.155510f, 22.148024f, 22.140541f, 22.133062f, 22.125591f, 22.118124f,
22.110661f, 22.103205f, 22.095753f, 22.088305f, 22.080862f, 22.073425f,
22.065992f, 22.058567f, 22.051144f, 22.043726f, 22.036314f, 22.028908f,
22.021505f, 22.014109f, 22.006716f, 21.999329f, 21.991947f, 21.984570f,
21.977196f, 21.969830f, 21.962467f, 21.955109f, 21.947756f, 21.940409f,
21.933065f, 21.925728f, 21.918394f, 21.911066f, 21.903744f, 21.896425f,
21.889112f, 21.881804f, 21.874500f, 21.867201f, 21.859907f, 21.852617f,
21.845333f, 21.838055f, 21.830780f, 21.823509f, 21.816244f, 21.808985f,
21.801729f, 21.794479f, 21.787233f, 21.779993f, 21.772757f, 21.765526f,
21.758301f, 21.751080f, 21.743862f, 21.736650f, 21.729443f, 21.722240f,
21.715044f, 21.707850f, 21.700663f, 21.693480f, 21.686300f, 21.679127f,
21.671957f, 21.664793f, 21.657635f, 21.650478f, 21.643330f, 21.636183f,
21.629044f, 21.621906f, 21.614777f, 21.607649f, 21.600527f, 21.593410f,
21.586298f, 21.579189f, 21.572086f, 21.564989f, 21.557896f, 21.550806f,
21.543722f, 21.536642f, 21.529566f, 21.522495f, 21.515430f, 21.508369f,
21.501312f, 21.494261f, 21.487213f, 21.480171f, 21.473133f, 21.466099f,
21.459070f, 21.452045f, 21.445026f, 21.438011f, 21.431000f, 21.423994f,
21.416994f, 21.409996f, 21.403004f, 21.396017f, 21.389034f, 21.382055f,
21.375082f, 21.368113f, 21.361147f, 21.354187f, 21.347231f, 21.340281f,
21.333334f, 21.326391f, 21.319454f, 21.312521f, 21.305592f, 21.298668f,
21.291748f, 21.284832f, 21.277922f, 21.271015f, 21.264114f, 21.257217f,
21.250324f, 21.243437f, 21.236551f, 21.229673f, 21.222797f, 21.215927f,
21.209061f, 21.202200f, 21.195343f, 21.188490f, 21.181643f, 21.174799f,
21.167959f, 21.161123f, 21.154293f, 21.147467f, 21.140646f, 21.133827f,
21.127014f, 21.120207f, 21.113401f, 21.106602f, 21.099808f, 21.093016f,
21.086229f, 21.079447f, 21.072668f, 21.065895f, 21.059126f, 21.052361f,
21.045601f, 21.038845f, 21.032093f, 21.025345f, 21.018602f, 21.011864f,
21.005129f, 20.998398f, 20.991673f, 20.984951f, 20.978233f, 20.971519f,
20.964811f, 20.958107f, 20.951406f, 20.944712f, 20.938019f, 20.931332f,
20.924648f, 20.917971f, 20.911295f, 20.904625f, 20.897959f, 20.891298f,
20.884640f, 20.877987f, 20.871338f, 20.864693f, 20.858051f, 20.851416f,
20.844784f, 20.838156f, 20.831532f, 20.824913f, 20.818296f, 20.811686f,
20.805079f, 20.798477f, 20.791878f, 20.785284f, 20.778694f, 20.772108f,
20.765526f, 20.758949f, 20.752375f, 20.745806f, 20.739241f, 20.732679f,
20.726122f, 20.719570f, 20.713022f, 20.706476f, 20.699936f, 20.693401f,
20.686869f, 20.680342f, 20.673817f, 20.667297f, 20.660782f, 20.654270f,
20.647762f, 20.641260f, 20.634760f, 20.628265f, 20.621775f, 20.615288f,
20.608805f, 20.602325f, 20.595852f, 20.589380f, 20.582914f, 20.576452f,
20.569994f, 20.563540f, 20.557089f, 20.550642f, 20.544201f, 20.537762f,
20.531328f, 20.524899f, 20.518473f, 20.512051f, 20.505632f, 20.499218f,
20.492807f, 20.486403f, 20.480000f, 20.473602f, 20.467209f, 20.460817f,
20.454432f, 20.448050f, 20.441671f, 20.435297f, 20.428928f, 20.422562f,
20.416199f, 20.409842f, 20.403486f, 20.397137f, 20.390791f, 20.384447f,
20.378109f, 20.371775f, 20.365444f, 20.359118f, 20.352795f, 20.346476f,
20.340162f, 20.333851f, 20.327543f, 20.321239f, 20.314941f, 20.308645f,
20.302355f, 20.296066f, 20.289783f, 20.283504f, 20.277227f, 20.270956f,
20.264688f, 20.258423f, 20.252163f, 20.245907f, 20.239655f, 20.233406f,
20.227161f, 20.220919f, 20.214682f, 20.208448f, 20.202219f, 20.195993f,
20.189772f, 20.183554f, 20.177340f, 20.171129f, 20.164923f, 20.158720f,
20.152521f, 20.146326f, 20.140135f, 20.133947f, 20.127764f, 20.121584f,
20.115408f, 20.109236f, 20.103067f, 20.096903f, 20.090742f, 20.084585f,
20.078432f, 20.072281f, 20.066135f, 20.059994f, 20.053856f, 20.047722f,
20.041590f, 20.035463f, 20.029341f, 20.023220f, 20.017105f, 20.010992f,
20.004885f, 19.998779f, 19.992678f, 19.986582f, 19.980488f, 19.974398f,
19.968311f, 19.962229f, 19.956152f, 19.950077f, 19.944004f, 19.937937f,
19.931873f, 19.925814f, 19.919756f, 19.913704f, 19.907656f, 19.901609f,
19.895567f, 19.889530f, 19.883495f, 19.877464f, 19.871437f, 19.865414f,
19.859394f, 19.853378f, 19.847364f, 19.841356f, 19.835352f, 19.829350f,
19.823351f, 19.817358f, 19.811367f, 19.805380f, 19.799397f, 19.793415f,
19.787439f, 19.781467f, 19.775497f, 19.769533f, 19.763571f, 19.757612f,
19.751657f, 19.745707f, 19.739759f, 19.733814f, 19.727875f, 19.721937f,
19.716005f, 19.710075f, 19.704149f, 19.698227f, 19.692308f, 19.686392f,
19.680481f, 19.674572f, 19.668667f, 19.662766f, 19.656868f, 19.650974f,
19.645084f, 19.639196f, 19.633314f, 19.627434f, 19.621557f, 19.615685f,
19.609814f, 19.603949f, 19.598085f, 19.592228f, 19.586372f, 19.580521f,
19.574671f, 19.568827f, 19.562984f, 19.557148f, 19.551313f, 19.545481f,
19.539654f, 19.533831f, 19.528009f, 19.522192f, 19.516378f, 19.510569f,
19.504763f, 19.498959f, 19.493158f, 19.487362f, 19.481569f, 19.475780f,
19.469994f, 19.464212f, 19.458433f, 19.452656f, 19.446884f, 19.441116f,
19.435350f, 19.429588f, 19.423830f, 19.418074f, 19.412323f, 19.406574f,
19.400829f, 19.395088f, 19.389349f, 19.383614f, 19.377882f, 19.372154f,
19.366430f, 19.360708f, 19.354992f, 19.349277f, 19.343565f, 19.337858f,
19.332153f, 19.326452f, 19.320755f, 19.315060f, 19.309370f, 19.303682f,
19.297998f, 19.292316f, 19.286638f, 19.280966f, 19.275293f, 19.269627f,
19.263962f, 19.258301f, 19.252644f, 19.246990f, 19.241339f, 19.235691f,
19.230047f, 19.224405f, 19.218769f, 19.213135f, 19.207502f, 19.201876f,
19.196251f, 19.190630f, 19.185011f, 19.179398f, 19.173786f, 19.168179f,
19.162573f, 19.156971f, 19.151373f, 19.145779f, 19.140186f, 19.134598f,
19.129013f, 19.123432f, 19.117853f, 19.112278f, 19.106705f, 19.101137f,
19.095572f, 19.090010f, 19.084450f, 19.078894f, 19.073341f, 19.067791f,
19.062246f, 19.056702f, 19.051163f, 19.045626f, 19.040092f, 19.034563f,
19.029036f, 19.023512f, 19.017992f, 19.012474f, 19.006960f, 19.001450f,
18.995941f, 18.990438f, 18.984936f, 18.979439f, 18.973944f, 18.968452f,
18.962963f, 18.957478f, 18.951996f, 18.946516f, 18.941040f, 18.935568f,
18.930098f, 18.924631f, 18.919168f, 18.913708f, 18.908251f, 18.902798f,
18.897346f, 18.891899f, 18.886456f, 18.881014f, 18.875576f, 18.870142f,
18.864710f, 18.859280f, 18.853855f, 18.848433f, 18.843014f, 18.837597f,
18.832184f, 18.826775f, 18.821367f, 18.815964f, 18.810562f, 18.805164f,
18.799770f, 18.794378f, 18.788990f, 18.783606f, 18.778223f, 18.772844f,
18.767469f, 18.762096f, 18.756725f, 18.751360f, 18.745995f, 18.740635f,
18.735277f, 18.729923f, 18.724571f, 18.719223f, 18.713879f, 18.708536f,
18.703196f, 18.697861f, 18.692528f, 18.687197f, 18.681870f, 18.676546f,
18.671225f, 18.665907f, 18.660593f, 18.655281f, 18.649971f, 18.644667f,
18.639362f, 18.634064f, 18.628767f, 18.623472f, 18.618181f, 18.612894f,
18.607609f, 18.602327f, 18.597050f, 18.591774f, 18.586500f, 18.581230f,
18.575964f, 18.570700f, 18.565439f, 18.560181f, 18.554926f, 18.549675f,
18.544426f, 18.539179f, 18.533937f, 18.528696f, 18.523460f, 18.518225f,
18.512995f, 18.507767f, 18.502541f, 18.497318f, 18.492100f, 18.486883f,
18.481670f, 18.476460f, 18.471251f, 18.466047f, 18.460846f, 18.455647f,
18.450451f, 18.445257f, 18.440067f, 18.434881f, 18.429697f, 18.424515f,
18.419336f, 18.414162f, 18.408989f, 18.403820f, 18.398653f, 18.393488f,
18.388329f, 18.383169f, 18.378016f, 18.372862f, 18.367714f, 18.362566f,
18.357424f, 18.352282f, 18.347145f, 18.342009f, 18.336878f, 18.331749f,
18.326622f, 18.321499f, 18.316378f, 18.311260f, 18.306145f, 18.301033f,
18.295923f, 18.290817f, 18.285715f, 18.280613f, 18.275517f, 18.270420f,
18.265329f, 18.260241f, 18.255154f, 18.250071f, 18.244989f, 18.239910f,
18.234837f, 18.229763f, 18.224693f, 18.219627f, 18.214563f, 18.209503f,
18.204445f, 18.199389f, 18.194336f, 18.189287f, 18.184240f, 18.179195f,
18.174154f, 18.169115f, 18.164080f, 18.159046f, 18.154016f, 18.148989f,
18.143965f, 18.138943f, 18.133924f, 18.128908f, 18.123894f, 18.118883f,
18.113874f, 18.108870f, 18.103867f, 18.098867f, 18.093870f, 18.088877f,
18.083885f, 18.078897f, 18.073910f, 18.068928f, 18.063948f, 18.058969f,
18.053995f, 18.049023f, 18.044052f, 18.039085f, 18.034122f, 18.029161f,
18.024202f, 18.019247f, 18.014294f, 18.009344f, 18.004396f, 17.999451f,
17.994509f, 17.989569f, 17.984632f, 17.979698f, 17.974768f, 17.969839f,
17.964912f, 17.959990f, 17.955069f, 17.950151f, 17.945236f, 17.940323f,
17.935413f, 17.930506f, 17.925602f, 17.920700f, 17.915800f, 17.910904f,
17.906012f, 17.901119f, 17.896231f, 17.891346f, 17.886463f, 17.881582f,
17.876705f, 17.871830f, 17.866957f, 17.862087f, 17.857222f, 17.852356f,
17.847494f, 17.842636f, 17.837778f, 17.832926f, 17.828074f, 17.823225f,
17.818380f, 17.813536f, 17.808695f, 17.803858f, 17.799023f, 17.794189f,
17.789360f, 17.784533f, 17.779707f, 17.774885f, 17.770065f, 17.765247f,
17.760433f, 17.755621f, 17.750813f, 17.746006f, 17.741201f, 17.736401f,
17.731602f, 17.726805f, 17.722012f, 17.717220f, 17.712433f, 17.707647f,
17.702864f, 17.698082f, 17.693304f, 17.688530f, 17.683756f, 17.678986f,
17.674217f, 17.669453f, 17.664690f, 17.659929f, 17.655172f, 17.650417f,
17.645664f, 17.640915f, 17.636168f, 17.631424f, 17.626680f, 17.621941f,
17.617205f, 17.612471f, 17.607738f, 17.603008f, 17.598282f, 17.593557f,
17.588835f, 17.584116f, 17.579399f, 17.574684f, 17.569973f, 17.565264f,
17.560556f, 17.555853f, 17.551151f, 17.546452f, 17.541756f, 17.537062f,
17.532370f, 17.527681f, 17.522995f, 17.518311f, 17.513630f, 17.508949f,
17.504274f, 17.499599f, 17.494928f, 17.490259f, 17.485592f, 17.480928f,
17.476267f, 17.471607f, 17.466951f, 17.462297f, 17.457645f, 17.452995f,
17.448349f, 17.443705f, 17.439064f, 17.434423f, 17.429787f, 17.425154f,
17.420521f, 17.415892f, 17.411264f, 17.406641f, 17.402018f, 17.397398f,
17.392782f, 17.388166f, 17.383554f, 17.378944f, 17.374338f, 17.369732f,
17.365129f, 17.360529f, 17.355932f, 17.351337f, 17.346745f, 17.342154f,
17.337566f, 17.332981f, 17.328398f, 17.323816f, 17.319239f, 17.314663f,
17.310089f, 17.305519f, 17.300951f, 17.296385f, 17.291821f, 17.287260f,
17.282700f, 17.278145f, 17.273590f, 17.269039f, 17.264488f, 17.259943f,
17.255398f, 17.250856f, 17.246315f, 17.241779f, 17.237244f, 17.232712f,
17.228180f, 17.223654f, 17.219128f, 17.214605f, 17.210085f, 17.205566f,
17.201050f, 17.196537f, 17.192024f, 17.187517f, 17.183010f, 17.178507f,
17.174004f, 17.169504f, 17.165009f, 17.160513f, 17.156021f, 17.151531f,
17.147043f, 17.142559f, 17.138075f, 17.133595f, 17.129116f, 17.124641f,
17.120167f, 17.115696f, 17.111227f, 17.106760f, 17.102297f, 17.097836f,
17.093374f, 17.088919f, 17.084463f, 17.080011f, 17.075560f, 17.071112f,
17.066668f, 17.062223f, 17.057783f, 17.053343f, 17.048908f, 17.044474f,
17.040041f, 17.035612f, 17.031185f, 17.026760f, 17.022337f, 17.017918f,
17.013500f, 17.009085f, 17.004671f, 17.000259f, 16.995852f, 16.991444f,
16.987040f, 16.982637f, 16.978239f, 16.973841f, 16.969446f, 16.965054f,
16.960663f, 16.956274f, 16.951889f, 16.947504f, 16.943123f, 16.938744f,
16.934366f, 16.929993f, 16.925619f, 16.921249f, 16.916882f, 16.912516f,
16.908154f, 16.903791f, 16.899433f, 16.895077f, 16.890722f, 16.886370f,
16.882019f, 16.877672f, 16.873327f, 16.868984f, 16.864643f, 16.860304f,
16.855967f, 16.851633f, 16.847301f, 16.842972f, 16.838644f, 16.834318f,
16.829994f, 16.825674f, 16.821356f, 16.817039f, 16.812725f, 16.808413f,
16.804102f, 16.799795f, 16.795490f, 16.791185f, 16.786884f, 16.782587f,
16.778290f, 16.773994f, 16.769703f, 16.765413f, 16.761126f, 16.756840f,
16.752556f, 16.748276f, 16.743996f, 16.739719f, 16.735445f, 16.731173f,
16.726902f, 16.722633f, 16.718367f, 16.714104f, 16.709843f, 16.705582f,
16.701324f, 16.697069f, 16.692818f, 16.688566f, 16.684319f, 16.680071f,
16.675827f, 16.671585f, 16.667345f, 16.663107f, 16.658871f, 16.654638f,
16.650406f, 16.646177f, 16.641951f, 16.637726f, 16.633503f, 16.629282f,
16.625063f, 16.620848f, 16.616632f, 16.612421f, 16.608212f, 16.604004f,
16.599798f, 16.595594f, 16.591393f, 16.587193f, 16.582996f, 16.578800f,
16.574608f, 16.570417f, 16.566229f, 16.562042f, 16.557858f, 16.553675f,
16.549496f, 16.545317f, 16.541142f, 16.536966f, 16.532795f, 16.528625f,
16.524458f, 16.520292f, 16.516129f, 16.511969f, 16.507809f, 16.503651f,
16.499496f, 16.495344f, 16.491192f, 16.487043f, 16.482897f, 16.478752f,
16.474611f, 16.470470f, 16.466331f, 16.462196f, 16.458061f, 16.453930f,
16.449799f, 16.445671f, 16.441545f, 16.437422f, 16.433300f, 16.429180f,
16.425062f, 16.420948f, 16.416834f, 16.412722f, 16.408613f, 16.404505f,
16.400400f, 16.396297f, 16.392197f, 16.388098f, 16.384001f, 16.379906f,
16.375813f, 16.371721f, 16.367632f, 16.363546f, 16.359461f, 16.355377f,
16.351297f, 16.347219f, 16.343142f, 16.339067f, 16.334995f, 16.330925f,
16.326857f, 16.322790f, 16.318726f, 16.314663f, 16.310602f, 16.306543f,
16.302488f, 16.298433f, 16.294380f, 16.290331f, 16.286282f, 16.282236f,
16.278193f, 16.274149f, 16.270109f, 16.266071f, 16.262035f, 16.258001f,
16.253969f, 16.249939f, 16.245911f, 16.241884f, 16.237860f, 16.233837f,
16.229816f, 16.225798f, 16.221783f, 16.217768f, 16.213755f, 16.209745f,
16.205736f, 16.201731f, 16.197725f, 16.193724f, 16.189724f, 16.185724f,
16.181728f, 16.177734f, 16.173742f, 16.169750f, 16.165762f, 16.161776f,
16.157791f, 16.153809f, 16.149828f, 16.145849f, 16.141872f, 16.137897f,
16.133924f, 16.129953f, 16.125984f, 16.122017f, 16.118052f, 16.114088f,
16.110128f, 16.106169f, 16.102211f, 16.098255f, 16.094303f, 16.090351f,
16.086401f, 16.082455f, 16.078508f, 16.074564f, 16.070623f, 16.066683f,
16.062746f, 16.058809f, 16.054874f, 16.050943f, 16.047012f, 16.043085f,
16.039158f, 16.035234f, 16.031311f, 16.027391f, 16.023472f, 16.019556f,
16.015640f, 16.011728f, 16.007816f, 16.003908f, 16.000000f
};
#ifdef LIBYUV_LITTLE_ENDIAN
#define WRITEWORD(p, v) *reinterpret_cast<uint32*>(p) = v
#else
static inline void WRITEWORD(uint8* p, uint32 v) {
p[0] = (uint8)(v & 255);
p[1] = (uint8)((v >> 8) & 255);
p[2] = (uint8)((v >> 16) & 255);
p[3] = (uint8)((v >> 24) & 255);
}
#endif
void RGB24ToARGBRow_C(const uint8* src_rgb24, uint8* dst_argb, int width) {
for (int x = 0; x < width; ++x) {
uint8 b = src_rgb24[0];
uint8 g = src_rgb24[1];
uint8 r = src_rgb24[2];
dst_argb[0] = b;
dst_argb[1] = g;
dst_argb[2] = r;
dst_argb[3] = 255u;
dst_argb += 4;
src_rgb24 += 3;
}
}
void RAWToARGBRow_C(const uint8* src_raw, uint8* dst_argb, int width) {
for (int x = 0; x < width; ++x) {
uint8 r = src_raw[0];
uint8 g = src_raw[1];
uint8 b = src_raw[2];
dst_argb[0] = b;
dst_argb[1] = g;
dst_argb[2] = r;
dst_argb[3] = 255u;
dst_argb += 4;
src_raw += 3;
}
}
void RGB565ToARGBRow_C(const uint8* src_rgb565, uint8* dst_argb, int width) {
for (int x = 0; x < width; ++x) {
uint8 b = src_rgb565[0] & 0x1f;
uint8 g = (src_rgb565[0] >> 5) | ((src_rgb565[1] & 0x07) << 3);
uint8 r = src_rgb565[1] >> 3;
dst_argb[0] = (b << 3) | (b >> 2);
dst_argb[1] = (g << 2) | (g >> 4);
dst_argb[2] = (r << 3) | (r >> 2);
dst_argb[3] = 255u;
dst_argb += 4;
src_rgb565 += 2;
}
}
void ARGB1555ToARGBRow_C(const uint8* src_argb1555, uint8* dst_argb,
int width) {
for (int x = 0; x < width; ++x) {
uint8 b = src_argb1555[0] & 0x1f;
uint8 g = (src_argb1555[0] >> 5) | ((src_argb1555[1] & 0x03) << 3);
uint8 r = (src_argb1555[1] & 0x7c) >> 2;
uint8 a = src_argb1555[1] >> 7;
dst_argb[0] = (b << 3) | (b >> 2);
dst_argb[1] = (g << 3) | (g >> 2);
dst_argb[2] = (r << 3) | (r >> 2);
dst_argb[3] = -a;
dst_argb += 4;
src_argb1555 += 2;
}
}
void ARGB4444ToARGBRow_C(const uint8* src_argb4444, uint8* dst_argb,
int width) {
for (int x = 0; x < width; ++x) {
uint8 b = src_argb4444[0] & 0x0f;
uint8 g = src_argb4444[0] >> 4;
uint8 r = src_argb4444[1] & 0x0f;
uint8 a = src_argb4444[1] >> 4;
dst_argb[0] = (b << 4) | b;
dst_argb[1] = (g << 4) | g;
dst_argb[2] = (r << 4) | r;
dst_argb[3] = (a << 4) | a;
dst_argb += 4;
src_argb4444 += 2;
}
}
void ARGBToRGB24Row_C(const uint8* src_argb, uint8* dst_rgb, int width) {
for (int x = 0; x < width; ++x) {
uint8 b = src_argb[0];
uint8 g = src_argb[1];
uint8 r = src_argb[2];
dst_rgb[0] = b;
dst_rgb[1] = g;
dst_rgb[2] = r;
dst_rgb += 3;
src_argb += 4;
}
}
void ARGBToRAWRow_C(const uint8* src_argb, uint8* dst_rgb, int width) {
for (int x = 0; x < width; ++x) {
uint8 b = src_argb[0];
uint8 g = src_argb[1];
uint8 r = src_argb[2];
dst_rgb[0] = r;
dst_rgb[1] = g;
dst_rgb[2] = b;
dst_rgb += 3;
src_argb += 4;
}
}
void ARGBToRGB565Row_C(const uint8* src_argb, uint8* dst_rgb, int width) {
for (int x = 0; x < width - 1; x += 2) {
uint8 b0 = src_argb[0] >> 3;
uint8 g0 = src_argb[1] >> 2;
uint8 r0 = src_argb[2] >> 3;
uint8 b1 = src_argb[4] >> 3;
uint8 g1 = src_argb[5] >> 2;
uint8 r1 = src_argb[6] >> 3;
WRITEWORD(dst_rgb, b0 | (g0 << 5) | (r0 << 11) |
(b1 << 16) | (g1 << 21) | (r1 << 27));
dst_rgb += 4;
src_argb += 8;
}
if (width & 1) {
uint8 b0 = src_argb[0] >> 3;
uint8 g0 = src_argb[1] >> 2;
uint8 r0 = src_argb[2] >> 3;
*reinterpret_cast<uint16*>(dst_rgb) = b0 | (g0 << 5) | (r0 << 11);
}
}
void ARGBToARGB1555Row_C(const uint8* src_argb, uint8* dst_rgb, int width) {
for (int x = 0; x < width - 1; x += 2) {
uint8 b0 = src_argb[0] >> 3;
uint8 g0 = src_argb[1] >> 3;
uint8 r0 = src_argb[2] >> 3;
uint8 a0 = src_argb[3] >> 7;
uint8 b1 = src_argb[4] >> 3;
uint8 g1 = src_argb[5] >> 3;
uint8 r1 = src_argb[6] >> 3;
uint8 a1 = src_argb[7] >> 7;
*reinterpret_cast<uint32*>(dst_rgb) =
b0 | (g0 << 5) | (r0 << 10) | (a0 << 15) |
(b1 << 16) | (g1 << 21) | (r1 << 26) | (a1 << 31);
dst_rgb += 4;
src_argb += 8;
}
if (width & 1) {
uint8 b0 = src_argb[0] >> 3;
uint8 g0 = src_argb[1] >> 3;
uint8 r0 = src_argb[2] >> 3;
uint8 a0 = src_argb[3] >> 7;
*reinterpret_cast<uint16*>(dst_rgb) =
b0 | (g0 << 5) | (r0 << 10) | (a0 << 15);
}
}
void ARGBToARGB4444Row_C(const uint8* src_argb, uint8* dst_rgb, int width) {
for (int x = 0; x < width - 1; x += 2) {
uint8 b0 = src_argb[0] >> 4;
uint8 g0 = src_argb[1] >> 4;
uint8 r0 = src_argb[2] >> 4;
uint8 a0 = src_argb[3] >> 4;
uint8 b1 = src_argb[4] >> 4;
uint8 g1 = src_argb[5] >> 4;
uint8 r1 = src_argb[6] >> 4;
uint8 a1 = src_argb[7] >> 4;
*reinterpret_cast<uint32*>(dst_rgb) =
b0 | (g0 << 4) | (r0 << 8) | (a0 << 12) |
(b1 << 16) | (g1 << 20) | (r1 << 24) | (a1 << 28);
dst_rgb += 4;
src_argb += 8;
}
if (width & 1) {
uint8 b0 = src_argb[0] >> 4;
uint8 g0 = src_argb[1] >> 4;
uint8 r0 = src_argb[2] >> 4;
uint8 a0 = src_argb[3] >> 4;
*reinterpret_cast<uint16*>(dst_rgb) =
b0 | (g0 << 4) | (r0 << 8) | (a0 << 12);
}
}
static __inline int RGBToY(uint8 r, uint8 g, uint8 b) {
return (66 * r + 129 * g + 25 * b + 0x1080) >> 8;
}
static __inline int RGBToU(uint8 r, uint8 g, uint8 b) {
return (112 * b - 74 * g - 38 * r + 0x8080) >> 8;
}
static __inline int RGBToV(uint8 r, uint8 g, uint8 b) {
return (112 * r - 94 * g - 18 * b + 0x8080) >> 8;
}
#define MAKEROWY(NAME, R, G, B, BPP) \
void NAME ## ToYRow_C(const uint8* src_argb0, uint8* dst_y, int width) { \
for (int x = 0; x < width; ++x) { \
dst_y[0] = RGBToY(src_argb0[R], src_argb0[G], src_argb0[B]); \
src_argb0 += BPP; \
dst_y += 1; \
} \
} \
void NAME ## ToUVRow_C(const uint8* src_rgb0, int src_stride_rgb, \
uint8* dst_u, uint8* dst_v, int width) { \
const uint8* src_rgb1 = src_rgb0 + src_stride_rgb; \
for (int x = 0; x < width - 1; x += 2) { \
uint8 ab = (src_rgb0[B] + src_rgb0[B + BPP] + \
src_rgb1[B] + src_rgb1[B + BPP]) >> 2; \
uint8 ag = (src_rgb0[G] + src_rgb0[G + BPP] + \
src_rgb1[G] + src_rgb1[G + BPP]) >> 2; \
uint8 ar = (src_rgb0[R] + src_rgb0[R + BPP] + \
src_rgb1[R] + src_rgb1[R + BPP]) >> 2; \
dst_u[0] = RGBToU(ar, ag, ab); \
dst_v[0] = RGBToV(ar, ag, ab); \
src_rgb0 += BPP * 2; \
src_rgb1 += BPP * 2; \
dst_u += 1; \
dst_v += 1; \
} \
if (width & 1) { \
uint8 ab = (src_rgb0[B] + src_rgb1[B]) >> 1; \
uint8 ag = (src_rgb0[G] + src_rgb1[G]) >> 1; \
uint8 ar = (src_rgb0[R] + src_rgb1[R]) >> 1; \
dst_u[0] = RGBToU(ar, ag, ab); \
dst_v[0] = RGBToV(ar, ag, ab); \
} \
}
MAKEROWY(ARGB, 2, 1, 0, 4)
MAKEROWY(BGRA, 1, 2, 3, 4)
MAKEROWY(ABGR, 0, 1, 2, 4)
MAKEROWY(RGBA, 3, 2, 1, 4)
MAKEROWY(RGB24, 2, 1, 0, 3)
MAKEROWY(RAW, 0, 1, 2, 3)
#undef MAKEROWY
// JPeg uses a variation on BT.601-1 full range
// y = 0.29900 * r + 0.58700 * g + 0.11400 * b
// u = -0.16874 * r - 0.33126 * g + 0.50000 * b + center
// v = 0.50000 * r - 0.41869 * g - 0.08131 * b + center
// BT.601 Mpeg range uses:
// b 0.1016 * 255 = 25.908 = 25
// g 0.5078 * 255 = 129.489 = 129
// r 0.2578 * 255 = 65.739 = 66
// JPeg 8 bit Y (not used):
// b 0.11400 * 256 = 29.184 = 29
// g 0.58700 * 256 = 150.272 = 150
// r 0.29900 * 256 = 76.544 = 77
// JPeg 7 bit Y:
// b 0.11400 * 128 = 14.592 = 15
// g 0.58700 * 128 = 75.136 = 75
// r 0.29900 * 128 = 38.272 = 38
// JPeg 8 bit U:
// b 0.50000 * 255 = 127.5 = 127
// g -0.33126 * 255 = -84.4713 = -84
// r -0.16874 * 255 = -43.0287 = -43
// JPeg 8 bit V:
// b -0.08131 * 255 = -20.73405 = -20
// g -0.41869 * 255 = -106.76595 = -107
// r 0.50000 * 255 = 127.5 = 127
static __inline int RGBToYJ(uint8 r, uint8 g, uint8 b) {
return (38 * r + 75 * g + 15 * b + 64) >> 7;
}
static __inline int RGBToUJ(uint8 r, uint8 g, uint8 b) {
return (127 * b - 84 * g - 43 * r + 0x8080) >> 8;
}
static __inline int RGBToVJ(uint8 r, uint8 g, uint8 b) {
return (127 * r - 107 * g - 20 * b + 0x8080) >> 8;
}
#define AVGB(a, b) (((a) + (b) + 1) >> 1)
#define MAKEROWYJ(NAME, R, G, B, BPP) \
void NAME ## ToYJRow_C(const uint8* src_argb0, uint8* dst_y, int width) { \
for (int x = 0; x < width; ++x) { \
dst_y[0] = RGBToYJ(src_argb0[R], src_argb0[G], src_argb0[B]); \
src_argb0 += BPP; \
dst_y += 1; \
} \
} \
void NAME ## ToUVJRow_C(const uint8* src_rgb0, int src_stride_rgb, \
uint8* dst_u, uint8* dst_v, int width) { \
const uint8* src_rgb1 = src_rgb0 + src_stride_rgb; \
for (int x = 0; x < width - 1; x += 2) { \
uint8 ab = AVGB(AVGB(src_rgb0[B], src_rgb1[B]), \
AVGB(src_rgb0[B + BPP], src_rgb1[B + BPP])); \
uint8 ag = AVGB(AVGB(src_rgb0[G], src_rgb1[G]), \
AVGB(src_rgb0[G + BPP], src_rgb1[G + BPP])); \
uint8 ar = AVGB(AVGB(src_rgb0[R], src_rgb1[R]), \
AVGB(src_rgb0[R + BPP], src_rgb1[R + BPP])); \
dst_u[0] = RGBToUJ(ar, ag, ab); \
dst_v[0] = RGBToVJ(ar, ag, ab); \
src_rgb0 += BPP * 2; \
src_rgb1 += BPP * 2; \
dst_u += 1; \
dst_v += 1; \
} \
if (width & 1) { \
uint8 ab = AVGB(src_rgb0[B], src_rgb1[B]); \
uint8 ag = AVGB(src_rgb0[G], src_rgb1[G]); \
uint8 ar = AVGB(src_rgb0[R], src_rgb1[R]); \
dst_u[0] = RGBToUJ(ar, ag, ab); \
dst_v[0] = RGBToVJ(ar, ag, ab); \
} \
}
MAKEROWYJ(ARGB, 2, 1, 0, 4)
#undef MAKEROWYJ
void RGB565ToYRow_C(const uint8* src_rgb565, uint8* dst_y, int width) {
for (int x = 0; x < width; ++x) {
uint8 b = src_rgb565[0] & 0x1f;
uint8 g = (src_rgb565[0] >> 5) | ((src_rgb565[1] & 0x07) << 3);
uint8 r = src_rgb565[1] >> 3;
b = (b << 3) | (b >> 2);
g = (g << 2) | (g >> 4);
r = (r << 3) | (r >> 2);
dst_y[0] = RGBToY(r, g, b);
src_rgb565 += 2;
dst_y += 1;
}
}
void ARGB1555ToYRow_C(const uint8* src_argb1555, uint8* dst_y, int width) {
for (int x = 0; x < width; ++x) {
uint8 b = src_argb1555[0] & 0x1f;
uint8 g = (src_argb1555[0] >> 5) | ((src_argb1555[1] & 0x03) << 3);
uint8 r = (src_argb1555[1] & 0x7c) >> 2;
b = (b << 3) | (b >> 2);
g = (g << 3) | (g >> 2);
r = (r << 3) | (r >> 2);
dst_y[0] = RGBToY(r, g, b);
src_argb1555 += 2;
dst_y += 1;
}
}
void ARGB4444ToYRow_C(const uint8* src_argb4444, uint8* dst_y, int width) {
for (int x = 0; x < width; ++x) {
uint8 b = src_argb4444[0] & 0x0f;
uint8 g = src_argb4444[0] >> 4;
uint8 r = src_argb4444[1] & 0x0f;
b = (b << 4) | b;
g = (g << 4) | g;
r = (r << 4) | r;
dst_y[0] = RGBToY(r, g, b);
src_argb4444 += 2;
dst_y += 1;
}
}
void RGB565ToUVRow_C(const uint8* src_rgb565, int src_stride_rgb565,
uint8* dst_u, uint8* dst_v, int width) {
const uint8* next_rgb565 = src_rgb565 + src_stride_rgb565;
for (int x = 0; x < width - 1; x += 2) {
uint8 b0 = src_rgb565[0] & 0x1f;
uint8 g0 = (src_rgb565[0] >> 5) | ((src_rgb565[1] & 0x07) << 3);
uint8 r0 = src_rgb565[1] >> 3;
uint8 b1 = src_rgb565[2] & 0x1f;
uint8 g1 = (src_rgb565[2] >> 5) | ((src_rgb565[3] & 0x07) << 3);
uint8 r1 = src_rgb565[3] >> 3;
uint8 b2 = next_rgb565[0] & 0x1f;
uint8 g2 = (next_rgb565[0] >> 5) | ((next_rgb565[1] & 0x07) << 3);
uint8 r2 = next_rgb565[1] >> 3;
uint8 b3 = next_rgb565[2] & 0x1f;
uint8 g3 = (next_rgb565[2] >> 5) | ((next_rgb565[3] & 0x07) << 3);
uint8 r3 = next_rgb565[3] >> 3;
uint8 b = (b0 + b1 + b2 + b3); // 565 * 4 = 787.
uint8 g = (g0 + g1 + g2 + g3);
uint8 r = (r0 + r1 + r2 + r3);
b = (b << 1) | (b >> 6); // 787 -> 888.
r = (r << 1) | (r >> 6);
dst_u[0] = RGBToU(r, g, b);
dst_v[0] = RGBToV(r, g, b);
src_rgb565 += 4;
next_rgb565 += 4;
dst_u += 1;
dst_v += 1;
}
if (width & 1) {
uint8 b0 = src_rgb565[0] & 0x1f;
uint8 g0 = (src_rgb565[0] >> 5) | ((src_rgb565[1] & 0x07) << 3);
uint8 r0 = src_rgb565[1] >> 3;
uint8 b2 = next_rgb565[0] & 0x1f;
uint8 g2 = (next_rgb565[0] >> 5) | ((next_rgb565[1] & 0x07) << 3);
uint8 r2 = next_rgb565[1] >> 3;
uint8 b = (b0 + b2); // 565 * 2 = 676.
uint8 g = (g0 + g2);
uint8 r = (r0 + r2);
b = (b << 2) | (b >> 4); // 676 -> 888
g = (g << 1) | (g >> 6);
r = (r << 2) | (r >> 4);
dst_u[0] = RGBToU(r, g, b);
dst_v[0] = RGBToV(r, g, b);
}
}
void ARGB1555ToUVRow_C(const uint8* src_argb1555, int src_stride_argb1555,
uint8* dst_u, uint8* dst_v, int width) {
const uint8* next_argb1555 = src_argb1555 + src_stride_argb1555;
for (int x = 0; x < width - 1; x += 2) {
uint8 b0 = src_argb1555[0] & 0x1f;
uint8 g0 = (src_argb1555[0] >> 5) | ((src_argb1555[1] & 0x03) << 3);
uint8 r0 = (src_argb1555[1] & 0x7c) >> 2;
uint8 b1 = src_argb1555[2] & 0x1f;
uint8 g1 = (src_argb1555[2] >> 5) | ((src_argb1555[3] & 0x03) << 3);
uint8 r1 = (src_argb1555[3] & 0x7c) >> 2;
uint8 b2 = next_argb1555[0] & 0x1f;
uint8 g2 = (next_argb1555[0] >> 5) | ((next_argb1555[1] & 0x03) << 3);
uint8 r2 = (next_argb1555[1] & 0x7c) >> 2;
uint8 b3 = next_argb1555[2] & 0x1f;
uint8 g3 = (next_argb1555[2] >> 5) | ((next_argb1555[3] & 0x03) << 3);
uint8 r3 = (next_argb1555[3] & 0x7c) >> 2;
uint8 b = (b0 + b1 + b2 + b3); // 555 * 4 = 777.
uint8 g = (g0 + g1 + g2 + g3);
uint8 r = (r0 + r1 + r2 + r3);
b = (b << 1) | (b >> 6); // 777 -> 888.
g = (g << 1) | (g >> 6);
r = (r << 1) | (r >> 6);
dst_u[0] = RGBToU(r, g, b);
dst_v[0] = RGBToV(r, g, b);
src_argb1555 += 4;
next_argb1555 += 4;
dst_u += 1;
dst_v += 1;
}
if (width & 1) {
uint8 b0 = src_argb1555[0] & 0x1f;
uint8 g0 = (src_argb1555[0] >> 5) | ((src_argb1555[1] & 0x03) << 3);
uint8 r0 = (src_argb1555[1] & 0x7c) >> 2;
uint8 b2 = next_argb1555[0] & 0x1f;
uint8 g2 = (next_argb1555[0] >> 5) | ((next_argb1555[1] & 0x03) << 3);
uint8 r2 = next_argb1555[1] >> 3;
uint8 b = (b0 + b2); // 555 * 2 = 666.
uint8 g = (g0 + g2);
uint8 r = (r0 + r2);
b = (b << 2) | (b >> 4); // 666 -> 888.
g = (g << 2) | (g >> 4);
r = (r << 2) | (r >> 4);
dst_u[0] = RGBToU(r, g, b);
dst_v[0] = RGBToV(r, g, b);
}
}
void ARGB4444ToUVRow_C(const uint8* src_argb4444, int src_stride_argb4444,
uint8* dst_u, uint8* dst_v, int width) {
const uint8* next_argb4444 = src_argb4444 + src_stride_argb4444;
for (int x = 0; x < width - 1; x += 2) {
uint8 b0 = src_argb4444[0] & 0x0f;
uint8 g0 = src_argb4444[0] >> 4;
uint8 r0 = src_argb4444[1] & 0x0f;
uint8 b1 = src_argb4444[2] & 0x0f;
uint8 g1 = src_argb4444[2] >> 4;
uint8 r1 = src_argb4444[3] & 0x0f;
uint8 b2 = next_argb4444[0] & 0x0f;
uint8 g2 = next_argb4444[0] >> 4;
uint8 r2 = next_argb4444[1] & 0x0f;
uint8 b3 = next_argb4444[2] & 0x0f;
uint8 g3 = next_argb4444[2] >> 4;
uint8 r3 = next_argb4444[3] & 0x0f;
uint8 b = (b0 + b1 + b2 + b3); // 444 * 4 = 666.
uint8 g = (g0 + g1 + g2 + g3);
uint8 r = (r0 + r1 + r2 + r3);
b = (b << 2) | (b >> 4); // 666 -> 888.
g = (g << 2) | (g >> 4);
r = (r << 2) | (r >> 4);
dst_u[0] = RGBToU(r, g, b);
dst_v[0] = RGBToV(r, g, b);
src_argb4444 += 4;
next_argb4444 += 4;
dst_u += 1;
dst_v += 1;
}
if (width & 1) {
uint8 b0 = src_argb4444[0] & 0x0f;
uint8 g0 = src_argb4444[0] >> 4;
uint8 r0 = src_argb4444[1] & 0x0f;
uint8 b2 = next_argb4444[0] & 0x0f;
uint8 g2 = next_argb4444[0] >> 4;
uint8 r2 = next_argb4444[1] & 0x0f;
uint8 b = (b0 + b2); // 444 * 2 = 555.
uint8 g = (g0 + g2);
uint8 r = (r0 + r2);
b = (b << 3) | (b >> 2); // 555 -> 888.
g = (g << 3) | (g >> 2);
r = (r << 3) | (r >> 2);
dst_u[0] = RGBToU(r, g, b);
dst_v[0] = RGBToV(r, g, b);
}
}
void ARGBToUV444Row_C(const uint8* src_argb,
uint8* dst_u, uint8* dst_v, int width) {
for (int x = 0; x < width; ++x) {
uint8 ab = src_argb[0];
uint8 ag = src_argb[1];
uint8 ar = src_argb[2];
dst_u[0] = RGBToU(ar, ag, ab);
dst_v[0] = RGBToV(ar, ag, ab);
src_argb += 4;
dst_u += 1;
dst_v += 1;
}
}
void ARGBToUV422Row_C(const uint8* src_argb,
uint8* dst_u, uint8* dst_v, int width) {
for (int x = 0; x < width - 1; x += 2) {
uint8 ab = (src_argb[0] + src_argb[4]) >> 1;
uint8 ag = (src_argb[1] + src_argb[5]) >> 1;
uint8 ar = (src_argb[2] + src_argb[6]) >> 1;
dst_u[0] = RGBToU(ar, ag, ab);
dst_v[0] = RGBToV(ar, ag, ab);
src_argb += 8;
dst_u += 1;
dst_v += 1;
}
if (width & 1) {
uint8 ab = src_argb[0];
uint8 ag = src_argb[1];
uint8 ar = src_argb[2];
dst_u[0] = RGBToU(ar, ag, ab);
dst_v[0] = RGBToV(ar, ag, ab);
}
}
void ARGBToUV411Row_C(const uint8* src_argb,
uint8* dst_u, uint8* dst_v, int width) {
for (int x = 0; x < width - 3; x += 4) {
uint8 ab = (src_argb[0] + src_argb[4] + src_argb[8] + src_argb[12]) >> 2;
uint8 ag = (src_argb[1] + src_argb[5] + src_argb[9] + src_argb[13]) >> 2;
uint8 ar = (src_argb[2] + src_argb[6] + src_argb[10] + src_argb[14]) >> 2;
dst_u[0] = RGBToU(ar, ag, ab);
dst_v[0] = RGBToV(ar, ag, ab);
src_argb += 16;
dst_u += 1;
dst_v += 1;
}
if ((width & 3) == 3) {
uint8 ab = (src_argb[0] + src_argb[4] + src_argb[8]) / 3;
uint8 ag = (src_argb[1] + src_argb[5] + src_argb[9]) / 3;
uint8 ar = (src_argb[2] + src_argb[6] + src_argb[10]) / 3;
dst_u[0] = RGBToU(ar, ag, ab);
dst_v[0] = RGBToV(ar, ag, ab);
} else if ((width & 3) == 2) {
uint8 ab = (src_argb[0] + src_argb[4]) >> 1;
uint8 ag = (src_argb[1] + src_argb[5]) >> 1;
uint8 ar = (src_argb[2] + src_argb[6]) >> 1;
dst_u[0] = RGBToU(ar, ag, ab);
dst_v[0] = RGBToV(ar, ag, ab);
} else if ((width & 3) == 1) {
uint8 ab = src_argb[0];
uint8 ag = src_argb[1];
uint8 ar = src_argb[2];
dst_u[0] = RGBToU(ar, ag, ab);
dst_v[0] = RGBToV(ar, ag, ab);
}
}
void ARGBGrayRow_C(const uint8* src_argb, uint8* dst_argb, int width) {
for (int x = 0; x < width; ++x) {
uint8 y = RGBToYJ(src_argb[2], src_argb[1], src_argb[0]);
dst_argb[2] = dst_argb[1] = dst_argb[0] = y;
dst_argb[3] = src_argb[3];
dst_argb += 4;
src_argb += 4;
}
}
// Convert a row of image to Sepia tone.
void ARGBSepiaRow_C(uint8* dst_argb, int width) {
for (int x = 0; x < width; ++x) {
int b = dst_argb[0];
int g = dst_argb[1];
int r = dst_argb[2];
int sb = (b * 17 + g * 68 + r * 35) >> 7;
int sg = (b * 22 + g * 88 + r * 45) >> 7;
int sr = (b * 24 + g * 98 + r * 50) >> 7;
// b does not over flow. a is preserved from original.
dst_argb[0] = sb;
dst_argb[1] = clamp255(sg);
dst_argb[2] = clamp255(sr);
dst_argb += 4;
}
}
// Apply color matrix to a row of image. Matrix is signed.
void ARGBColorMatrixRow_C(uint8* dst_argb, const int8* matrix_argb, int width) {
for (int x = 0; x < width; ++x) {
int b = dst_argb[0];
int g = dst_argb[1];
int r = dst_argb[2];
int a = dst_argb[3];
int sb = (b * matrix_argb[0] + g * matrix_argb[1] +
r * matrix_argb[2] + a * matrix_argb[3]) >> 7;
int sg = (b * matrix_argb[4] + g * matrix_argb[5] +
r * matrix_argb[6] + a * matrix_argb[7]) >> 7;
int sr = (b * matrix_argb[8] + g * matrix_argb[9] +
r * matrix_argb[10] + a * matrix_argb[11]) >> 7;
dst_argb[0] = Clamp(sb);
dst_argb[1] = Clamp(sg);
dst_argb[2] = Clamp(sr);
dst_argb += 4;
}
}
// Apply color table to a row of image.
void ARGBColorTableRow_C(uint8* dst_argb, const uint8* table_argb, int width) {
for (int x = 0; x < width; ++x) {
int b = dst_argb[0];
int g = dst_argb[1];
int r = dst_argb[2];
int a = dst_argb[3];
dst_argb[0] = table_argb[b * 4 + 0];
dst_argb[1] = table_argb[g * 4 + 1];
dst_argb[2] = table_argb[r * 4 + 2];
dst_argb[3] = table_argb[a * 4 + 3];
dst_argb += 4;
}
}
void ARGBQuantizeRow_C(uint8* dst_argb, int scale, int interval_size,
int interval_offset, int width) {
for (int x = 0; x < width; ++x) {
int b = dst_argb[0];
int g = dst_argb[1];
int r = dst_argb[2];
dst_argb[0] = (b * scale >> 16) * interval_size + interval_offset;
dst_argb[1] = (g * scale >> 16) * interval_size + interval_offset;
dst_argb[2] = (r * scale >> 16) * interval_size + interval_offset;
dst_argb += 4;
}
}
#define REPEAT8(v) (v) | ((v) << 8)
#define SHADE(f, v) v * f >> 24
void ARGBShadeRow_C(const uint8* src_argb, uint8* dst_argb, int width,
uint32 value) {
const uint32 b_scale = REPEAT8(value & 0xff);
const uint32 g_scale = REPEAT8((value >> 8) & 0xff);
const uint32 r_scale = REPEAT8((value >> 16) & 0xff);
const uint32 a_scale = REPEAT8(value >> 24);
for (int i = 0; i < width; ++i) {
const uint32 b = REPEAT8(src_argb[0]);
const uint32 g = REPEAT8(src_argb[1]);
const uint32 r = REPEAT8(src_argb[2]);
const uint32 a = REPEAT8(src_argb[3]);
dst_argb[0] = SHADE(b, b_scale);
dst_argb[1] = SHADE(g, g_scale);
dst_argb[2] = SHADE(r, r_scale);
dst_argb[3] = SHADE(a, a_scale);
src_argb += 4;
dst_argb += 4;
}
}
#undef REPEAT8
#undef SHADE
#define REPEAT8(v) (v) | ((v) << 8)
#define SHADE(f, v) v * f >> 16
void ARGBMultiplyRow_C(const uint8* src_argb0, const uint8* src_argb1,
uint8* dst_argb, int width) {
for (int i = 0; i < width; ++i) {
const uint32 b = REPEAT8(src_argb0[0]);
const uint32 g = REPEAT8(src_argb0[1]);
const uint32 r = REPEAT8(src_argb0[2]);
const uint32 a = REPEAT8(src_argb0[3]);
const uint32 b_scale = src_argb1[0];
const uint32 g_scale = src_argb1[1];
const uint32 r_scale = src_argb1[2];
const uint32 a_scale = src_argb1[3];
dst_argb[0] = SHADE(b, b_scale);
dst_argb[1] = SHADE(g, g_scale);
dst_argb[2] = SHADE(r, r_scale);
dst_argb[3] = SHADE(a, a_scale);
src_argb0 += 4;
src_argb1 += 4;
dst_argb += 4;
}
}
#undef REPEAT8
#undef SHADE
#define SHADE(f, v) clamp255(v + f)
void ARGBAddRow_C(const uint8* src_argb0, const uint8* src_argb1,
uint8* dst_argb, int width) {
for (int i = 0; i < width; ++i) {
const int b = src_argb0[0];
const int g = src_argb0[1];
const int r = src_argb0[2];
const int a = src_argb0[3];
const int b_add = src_argb1[0];
const int g_add = src_argb1[1];
const int r_add = src_argb1[2];
const int a_add = src_argb1[3];
dst_argb[0] = SHADE(b, b_add);
dst_argb[1] = SHADE(g, g_add);
dst_argb[2] = SHADE(r, r_add);
dst_argb[3] = SHADE(a, a_add);
src_argb0 += 4;
src_argb1 += 4;
dst_argb += 4;
}
}
#undef SHADE
#define SHADE(f, v) clamp0(f - v)
void ARGBSubtractRow_C(const uint8* src_argb0, const uint8* src_argb1,
uint8* dst_argb, int width) {
for (int i = 0; i < width; ++i) {
const int b = src_argb0[0];
const int g = src_argb0[1];
const int r = src_argb0[2];
const int a = src_argb0[3];
const int b_sub = src_argb1[0];
const int g_sub = src_argb1[1];
const int r_sub = src_argb1[2];
const int a_sub = src_argb1[3];
dst_argb[0] = SHADE(b, b_sub);
dst_argb[1] = SHADE(g, g_sub);
dst_argb[2] = SHADE(r, r_sub);
dst_argb[3] = SHADE(a, a_sub);
src_argb0 += 4;
src_argb1 += 4;
dst_argb += 4;
}
}
#undef SHADE
// Sobel functions which mimics SSSE3.
void SobelXRow_C(const uint8* src_y0, const uint8* src_y1, const uint8* src_y2,
uint8* dst_sobelx, int width) {
for (int i = 0; i < width; ++i) {
int a = src_y0[i];
int b = src_y1[i];
int c = src_y2[i];
int a_sub = src_y0[i + 2];
int b_sub = src_y1[i + 2];
int c_sub = src_y2[i + 2];
int a_diff = a - a_sub;
int b_diff = b - b_sub;
int c_diff = c - c_sub;
int sobel = Abs(a_diff + b_diff * 2 + c_diff);
dst_sobelx[i] = static_cast<uint8>(clamp255(sobel));
}
}
void SobelYRow_C(const uint8* src_y0, const uint8* src_y1,
uint8* dst_sobely, int width) {
for (int i = 0; i < width; ++i) {
int a = src_y0[i + 0];
int b = src_y0[i + 1];
int c = src_y0[i + 2];
int a_sub = src_y1[i + 0];
int b_sub = src_y1[i + 1];
int c_sub = src_y1[i + 2];
int a_diff = a - a_sub;
int b_diff = b - b_sub;
int c_diff = c - c_sub;
int sobel = Abs(a_diff + b_diff * 2 + c_diff);
dst_sobely[i] = static_cast<uint8>(clamp255(sobel));
}
}
void SobelRow_C(const uint8* src_sobelx, const uint8* src_sobely,
uint8* dst_argb, int width) {
for (int i = 0; i < width; ++i) {
int r = src_sobelx[i];
int b = src_sobely[i];
int s = clamp255(r + b);
dst_argb[0] = static_cast<uint8>(s);
dst_argb[1] = static_cast<uint8>(s);
dst_argb[2] = static_cast<uint8>(s);
dst_argb[3] = static_cast<uint8>(255u);
dst_argb += 4;
}
}
void SobelXYRow_C(const uint8* src_sobelx, const uint8* src_sobely,
uint8* dst_argb, int width) {
for (int i = 0; i < width; ++i) {
int r = src_sobelx[i];
int b = src_sobely[i];
int g = clamp255(r + b);
dst_argb[0] = static_cast<uint8>(b);
dst_argb[1] = static_cast<uint8>(g);
dst_argb[2] = static_cast<uint8>(r);
dst_argb[3] = static_cast<uint8>(255u);
dst_argb += 4;
}
}
void I400ToARGBRow_C(const uint8* src_y, uint8* dst_argb, int width) {
// Copy a Y to RGB.
for (int x = 0; x < width; ++x) {
uint8 y = src_y[0];
dst_argb[2] = dst_argb[1] = dst_argb[0] = y;
dst_argb[3] = 255u;
dst_argb += 4;
++src_y;
}
}
// C reference code that mimics the YUV assembly.
#define YG 74 /* static_cast<int8>(1.164 * 64 + 0.5) */
#define UB 127 /* min(63,static_cast<int8>(2.018 * 64)) */
#define UG -25 /* static_cast<int8>(-0.391 * 64 - 0.5) */
#define UR 0
#define VB 0
#define VG -52 /* static_cast<int8>(-0.813 * 64 - 0.5) */
#define VR 102 /* static_cast<int8>(1.596 * 64 + 0.5) */
// Bias
#define BB UB * 128 + VB * 128
#define BG UG * 128 + VG * 128
#define BR UR * 128 + VR * 128
static __inline void YuvPixel(uint8 y, uint8 u, uint8 v,
uint8* b, uint8* g, uint8* r) {
int32 y1 = (static_cast<int32>(y) - 16) * YG;
*b = Clamp(static_cast<int32>((u * UB + v * VB) - (BB) + y1) >> 6);
*g = Clamp(static_cast<int32>((u * UG + v * VG) - (BG) + y1) >> 6);
*r = Clamp(static_cast<int32>((u * UR + v * VR) - (BR) + y1) >> 6);
}
#if !defined(LIBYUV_DISABLE_NEON) && \
(defined(__ARM_NEON__) || defined(LIBYUV_NEON))
// C mimic assembly.
// TODO(fbarchard): Remove subsampling from Neon.
void I444ToARGBRow_C(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* rgb_buf,
int width) {
for (int x = 0; x < width - 1; x += 2) {
uint8 u = (src_u[0] + src_u[1] + 1) >> 1;
uint8 v = (src_v[0] + src_v[1] + 1) >> 1;
YuvPixel(src_y[0], u, v, rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
rgb_buf[3] = 255;
YuvPixel(src_y[1], u, v, rgb_buf + 4, rgb_buf + 5, rgb_buf + 6);
rgb_buf[7] = 255;
src_y += 2;
src_u += 2;
src_v += 2;
rgb_buf += 8; // Advance 2 pixels.
}
if (width & 1) {
YuvPixel(src_y[0], src_u[0], src_v[0],
rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
}
}
#else
void I444ToARGBRow_C(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* rgb_buf,
int width) {
for (int x = 0; x < width; ++x) {
YuvPixel(src_y[0], src_u[0], src_v[0],
rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
rgb_buf[3] = 255;
src_y += 1;
src_u += 1;
src_v += 1;
rgb_buf += 4; // Advance 1 pixel.
}
}
#endif
// Also used for 420
void I422ToARGBRow_C(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* rgb_buf,
int width) {
for (int x = 0; x < width - 1; x += 2) {
YuvPixel(src_y[0], src_u[0], src_v[0],
rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
rgb_buf[3] = 255;
YuvPixel(src_y[1], src_u[0], src_v[0],
rgb_buf + 4, rgb_buf + 5, rgb_buf + 6);
rgb_buf[7] = 255;
src_y += 2;
src_u += 1;
src_v += 1;
rgb_buf += 8; // Advance 2 pixels.
}
if (width & 1) {
YuvPixel(src_y[0], src_u[0], src_v[0],
rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
rgb_buf[3] = 255;
}
}
void I422ToRGB24Row_C(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* rgb_buf,
int width) {
for (int x = 0; x < width - 1; x += 2) {
YuvPixel(src_y[0], src_u[0], src_v[0],
rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
YuvPixel(src_y[1], src_u[0], src_v[0],
rgb_buf + 3, rgb_buf + 4, rgb_buf + 5);
src_y += 2;
src_u += 1;
src_v += 1;
rgb_buf += 6; // Advance 2 pixels.
}
if (width & 1) {
YuvPixel(src_y[0], src_u[0], src_v[0],
rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
}
}
void I422ToRAWRow_C(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* rgb_buf,
int width) {
for (int x = 0; x < width - 1; x += 2) {
YuvPixel(src_y[0], src_u[0], src_v[0],
rgb_buf + 2, rgb_buf + 1, rgb_buf + 0);
YuvPixel(src_y[1], src_u[0], src_v[0],
rgb_buf + 5, rgb_buf + 4, rgb_buf + 3);
src_y += 2;
src_u += 1;
src_v += 1;
rgb_buf += 6; // Advance 2 pixels.
}
if (width & 1) {
YuvPixel(src_y[0], src_u[0], src_v[0],
rgb_buf + 2, rgb_buf + 1, rgb_buf + 0);
}
}
void I422ToARGB4444Row_C(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* dst_argb4444,
int width) {
uint8 b0;
uint8 g0;
uint8 r0;
uint8 b1;
uint8 g1;
uint8 r1;
for (int x = 0; x < width - 1; x += 2) {
YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0);
YuvPixel(src_y[1], src_u[0], src_v[0], &b1, &g1, &r1);
b0 = b0 >> 4;
g0 = g0 >> 4;
r0 = r0 >> 4;
b1 = b1 >> 4;
g1 = g1 >> 4;
r1 = r1 >> 4;
*reinterpret_cast<uint32*>(dst_argb4444) = b0 | (g0 << 4) | (r0 << 8) |
(b1 << 16) | (g1 << 20) | (r1 << 24) | 0xf000f000;
src_y += 2;
src_u += 1;
src_v += 1;
dst_argb4444 += 4; // Advance 2 pixels.
}
if (width & 1) {
YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0);
b0 = b0 >> 4;
g0 = g0 >> 4;
r0 = r0 >> 4;
*reinterpret_cast<uint16*>(dst_argb4444) = b0 | (g0 << 4) | (r0 << 8) |
0xf000;
}
}
void I422ToARGB1555Row_C(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* dst_argb1555,
int width) {
uint8 b0;
uint8 g0;
uint8 r0;
uint8 b1;
uint8 g1;
uint8 r1;
for (int x = 0; x < width - 1; x += 2) {
YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0);
YuvPixel(src_y[1], src_u[0], src_v[0], &b1, &g1, &r1);
b0 = b0 >> 3;
g0 = g0 >> 3;
r0 = r0 >> 3;
b1 = b1 >> 3;
g1 = g1 >> 3;
r1 = r1 >> 3;
*reinterpret_cast<uint32*>(dst_argb1555) = b0 | (g0 << 5) | (r0 << 10) |
(b1 << 16) | (g1 << 21) | (r1 << 26) | 0x80008000;
src_y += 2;
src_u += 1;
src_v += 1;
dst_argb1555 += 4; // Advance 2 pixels.
}
if (width & 1) {
YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0);
b0 = b0 >> 3;
g0 = g0 >> 3;
r0 = r0 >> 3;
*reinterpret_cast<uint16*>(dst_argb1555) = b0 | (g0 << 5) | (r0 << 10) |
0x8000;
}
}
void I422ToRGB565Row_C(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* dst_rgb565,
int width) {
uint8 b0;
uint8 g0;
uint8 r0;
uint8 b1;
uint8 g1;
uint8 r1;
for (int x = 0; x < width - 1; x += 2) {
YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0);
YuvPixel(src_y[1], src_u[0], src_v[0], &b1, &g1, &r1);
b0 = b0 >> 3;
g0 = g0 >> 2;
r0 = r0 >> 3;
b1 = b1 >> 3;
g1 = g1 >> 2;
r1 = r1 >> 3;
*reinterpret_cast<uint32*>(dst_rgb565) = b0 | (g0 << 5) | (r0 << 11) |
(b1 << 16) | (g1 << 21) | (r1 << 27);
src_y += 2;
src_u += 1;
src_v += 1;
dst_rgb565 += 4; // Advance 2 pixels.
}
if (width & 1) {
YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0);
b0 = b0 >> 3;
g0 = g0 >> 2;
r0 = r0 >> 3;
*reinterpret_cast<uint16*>(dst_rgb565) = b0 | (g0 << 5) | (r0 << 11);
}
}
void I411ToARGBRow_C(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* rgb_buf,
int width) {
for (int x = 0; x < width - 3; x += 4) {
YuvPixel(src_y[0], src_u[0], src_v[0],
rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
rgb_buf[3] = 255;
YuvPixel(src_y[1], src_u[0], src_v[0],
rgb_buf + 4, rgb_buf + 5, rgb_buf + 6);
rgb_buf[7] = 255;
YuvPixel(src_y[2], src_u[0], src_v[0],
rgb_buf + 8, rgb_buf + 9, rgb_buf + 10);
rgb_buf[11] = 255;
YuvPixel(src_y[3], src_u[0], src_v[0],
rgb_buf + 12, rgb_buf + 13, rgb_buf + 14);
rgb_buf[15] = 255;
src_y += 4;
src_u += 1;
src_v += 1;
rgb_buf += 16; // Advance 4 pixels.
}
if (width & 2) {
YuvPixel(src_y[0], src_u[0], src_v[0],
rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
rgb_buf[3] = 255;
YuvPixel(src_y[1], src_u[0], src_v[0],
rgb_buf + 4, rgb_buf + 5, rgb_buf + 6);
rgb_buf[7] = 255;
src_y += 2;
rgb_buf += 8; // Advance 2 pixels.
}
if (width & 1) {
YuvPixel(src_y[0], src_u[0], src_v[0],
rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
rgb_buf[3] = 255;
}
}
void NV12ToARGBRow_C(const uint8* src_y,
const uint8* usrc_v,
uint8* rgb_buf,
int width) {
for (int x = 0; x < width - 1; x += 2) {
YuvPixel(src_y[0], usrc_v[0], usrc_v[1],
rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
rgb_buf[3] = 255;
YuvPixel(src_y[1], usrc_v[0], usrc_v[1],
rgb_buf + 4, rgb_buf + 5, rgb_buf + 6);
rgb_buf[7] = 255;
src_y += 2;
usrc_v += 2;
rgb_buf += 8; // Advance 2 pixels.
}
if (width & 1) {
YuvPixel(src_y[0], usrc_v[0], usrc_v[1],
rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
rgb_buf[3] = 255;
}
}
void NV21ToARGBRow_C(const uint8* src_y,
const uint8* src_vu,
uint8* rgb_buf,
int width) {
for (int x = 0; x < width - 1; x += 2) {
YuvPixel(src_y[0], src_vu[1], src_vu[0],
rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
rgb_buf[3] = 255;
YuvPixel(src_y[1], src_vu[1], src_vu[0],
rgb_buf + 4, rgb_buf + 5, rgb_buf + 6);
rgb_buf[7] = 255;
src_y += 2;
src_vu += 2;
rgb_buf += 8; // Advance 2 pixels.
}
if (width & 1) {
YuvPixel(src_y[0], src_vu[1], src_vu[0],
rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
rgb_buf[3] = 255;
}
}
void NV12ToRGB565Row_C(const uint8* src_y,
const uint8* usrc_v,
uint8* dst_rgb565,
int width) {
uint8 b0;
uint8 g0;
uint8 r0;
uint8 b1;
uint8 g1;
uint8 r1;
for (int x = 0; x < width - 1; x += 2) {
YuvPixel(src_y[0], usrc_v[0], usrc_v[1], &b0, &g0, &r0);
YuvPixel(src_y[1], usrc_v[0], usrc_v[1], &b1, &g1, &r1);
b0 = b0 >> 3;
g0 = g0 >> 2;
r0 = r0 >> 3;
b1 = b1 >> 3;
g1 = g1 >> 2;
r1 = r1 >> 3;
*reinterpret_cast<uint32*>(dst_rgb565) = b0 | (g0 << 5) | (r0 << 11) |
(b1 << 16) | (g1 << 21) | (r1 << 27);
src_y += 2;
usrc_v += 2;
dst_rgb565 += 4; // Advance 2 pixels.
}
if (width & 1) {
YuvPixel(src_y[0], usrc_v[0], usrc_v[1], &b0, &g0, &r0);
b0 = b0 >> 3;
g0 = g0 >> 2;
r0 = r0 >> 3;
*reinterpret_cast<uint16*>(dst_rgb565) = b0 | (g0 << 5) | (r0 << 11);
}
}
void NV21ToRGB565Row_C(const uint8* src_y,
const uint8* vsrc_u,
uint8* dst_rgb565,
int width) {
uint8 b0;
uint8 g0;
uint8 r0;
uint8 b1;
uint8 g1;
uint8 r1;
for (int x = 0; x < width - 1; x += 2) {
YuvPixel(src_y[0], vsrc_u[1], vsrc_u[0], &b0, &g0, &r0);
YuvPixel(src_y[1], vsrc_u[1], vsrc_u[0], &b1, &g1, &r1);
b0 = b0 >> 3;
g0 = g0 >> 2;
r0 = r0 >> 3;
b1 = b1 >> 3;
g1 = g1 >> 2;
r1 = r1 >> 3;
*reinterpret_cast<uint32*>(dst_rgb565) = b0 | (g0 << 5) | (r0 << 11) |
(b1 << 16) | (g1 << 21) | (r1 << 27);
src_y += 2;
vsrc_u += 2;
dst_rgb565 += 4; // Advance 2 pixels.
}
if (width & 1) {
YuvPixel(src_y[0], vsrc_u[1], vsrc_u[0], &b0, &g0, &r0);
b0 = b0 >> 3;
g0 = g0 >> 2;
r0 = r0 >> 3;
*reinterpret_cast<uint16*>(dst_rgb565) = b0 | (g0 << 5) | (r0 << 11);
}
}
void YUY2ToARGBRow_C(const uint8* src_yuy2,
uint8* rgb_buf,
int width) {
for (int x = 0; x < width - 1; x += 2) {
YuvPixel(src_yuy2[0], src_yuy2[1], src_yuy2[3],
rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
rgb_buf[3] = 255;
YuvPixel(src_yuy2[2], src_yuy2[1], src_yuy2[3],
rgb_buf + 4, rgb_buf + 5, rgb_buf + 6);
rgb_buf[7] = 255;
src_yuy2 += 4;
rgb_buf += 8; // Advance 2 pixels.
}
if (width & 1) {
YuvPixel(src_yuy2[0], src_yuy2[1], src_yuy2[3],
rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
rgb_buf[3] = 255;
}
}
void UYVYToARGBRow_C(const uint8* src_uyvy,
uint8* rgb_buf,
int width) {
for (int x = 0; x < width - 1; x += 2) {
YuvPixel(src_uyvy[1], src_uyvy[0], src_uyvy[2],
rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
rgb_buf[3] = 255;
YuvPixel(src_uyvy[3], src_uyvy[0], src_uyvy[2],
rgb_buf + 4, rgb_buf + 5, rgb_buf + 6);
rgb_buf[7] = 255;
src_uyvy += 4;
rgb_buf += 8; // Advance 2 pixels.
}
if (width & 1) {
YuvPixel(src_uyvy[1], src_uyvy[0], src_uyvy[2],
rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
rgb_buf[3] = 255;
}
}
void I422ToBGRARow_C(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* rgb_buf,
int width) {
for (int x = 0; x < width - 1; x += 2) {
YuvPixel(src_y[0], src_u[0], src_v[0],
rgb_buf + 3, rgb_buf + 2, rgb_buf + 1);
rgb_buf[0] = 255;
YuvPixel(src_y[1], src_u[0], src_v[0],
rgb_buf + 7, rgb_buf + 6, rgb_buf + 5);
rgb_buf[4] = 255;
src_y += 2;
src_u += 1;
src_v += 1;
rgb_buf += 8; // Advance 2 pixels.
}
if (width & 1) {
YuvPixel(src_y[0], src_u[0], src_v[0],
rgb_buf + 3, rgb_buf + 2, rgb_buf + 1);
rgb_buf[0] = 255;
}
}
void I422ToABGRRow_C(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* rgb_buf,
int width) {
for (int x = 0; x < width - 1; x += 2) {
YuvPixel(src_y[0], src_u[0], src_v[0],
rgb_buf + 2, rgb_buf + 1, rgb_buf + 0);
rgb_buf[3] = 255;
YuvPixel(src_y[1], src_u[0], src_v[0],
rgb_buf + 6, rgb_buf + 5, rgb_buf + 4);
rgb_buf[7] = 255;
src_y += 2;
src_u += 1;
src_v += 1;
rgb_buf += 8; // Advance 2 pixels.
}
if (width & 1) {
YuvPixel(src_y[0], src_u[0], src_v[0],
rgb_buf + 2, rgb_buf + 1, rgb_buf + 0);
rgb_buf[3] = 255;
}
}
void I422ToRGBARow_C(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* rgb_buf,
int width) {
for (int x = 0; x < width - 1; x += 2) {
YuvPixel(src_y[0], src_u[0], src_v[0],
rgb_buf + 1, rgb_buf + 2, rgb_buf + 3);
rgb_buf[0] = 255;
YuvPixel(src_y[1], src_u[0], src_v[0],
rgb_buf + 5, rgb_buf + 6, rgb_buf + 7);
rgb_buf[4] = 255;
src_y += 2;
src_u += 1;
src_v += 1;
rgb_buf += 8; // Advance 2 pixels.
}
if (width & 1) {
YuvPixel(src_y[0], src_u[0], src_v[0],
rgb_buf + 1, rgb_buf + 2, rgb_buf + 3);
rgb_buf[0] = 255;
}
}
void YToARGBRow_C(const uint8* src_y, uint8* rgb_buf, int width) {
for (int x = 0; x < width - 1; x += 2) {
YuvPixel(src_y[0], 128, 128,
rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
rgb_buf[3] = 255;
YuvPixel(src_y[1], 128, 128,
rgb_buf + 4, rgb_buf + 5, rgb_buf + 6);
rgb_buf[7] = 255;
src_y += 2;
rgb_buf += 8; // Advance 2 pixels.
}
if (width & 1) {
YuvPixel(src_y[0], 128, 128,
rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
rgb_buf[3] = 255;
}
}
void MirrorRow_C(const uint8* src, uint8* dst, int width) {
src += width - 1;
for (int x = 0; x < width - 1; x += 2) {
dst[x] = src[0];
dst[x + 1] = src[-1];
src -= 2;
}
if (width & 1) {
dst[width - 1] = src[0];
}
}
void MirrorUVRow_C(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width) {
src_uv += (width - 1) << 1;
for (int x = 0; x < width - 1; x += 2) {
dst_u[x] = src_uv[0];
dst_u[x + 1] = src_uv[-2];
dst_v[x] = src_uv[1];
dst_v[x + 1] = src_uv[-2 + 1];
src_uv -= 4;
}
if (width & 1) {
dst_u[width - 1] = src_uv[0];
dst_v[width - 1] = src_uv[1];
}
}
void ARGBMirrorRow_C(const uint8* src, uint8* dst, int width) {
const uint32* src32 = reinterpret_cast<const uint32*>(src);
uint32* dst32 = reinterpret_cast<uint32*>(dst);
src32 += width - 1;
for (int x = 0; x < width - 1; x += 2) {
dst32[x] = src32[0];
dst32[x + 1] = src32[-1];
src32 -= 2;
}
if (width & 1) {
dst32[width - 1] = src32[0];
}
}
void SplitUVRow_C(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width) {
for (int x = 0; x < width - 1; x += 2) {
dst_u[x] = src_uv[0];
dst_u[x + 1] = src_uv[2];
dst_v[x] = src_uv[1];
dst_v[x + 1] = src_uv[3];
src_uv += 4;
}
if (width & 1) {
dst_u[width - 1] = src_uv[0];
dst_v[width - 1] = src_uv[1];
}
}
void MergeUVRow_C(const uint8* src_u, const uint8* src_v, uint8* dst_uv,
int width) {
for (int x = 0; x < width - 1; x += 2) {
dst_uv[0] = src_u[x];
dst_uv[1] = src_v[x];
dst_uv[2] = src_u[x + 1];
dst_uv[3] = src_v[x + 1];
dst_uv += 4;
}
if (width & 1) {
dst_uv[0] = src_u[width - 1];
dst_uv[1] = src_v[width - 1];
}
}
void CopyRow_C(const uint8* src, uint8* dst, int count) {
memcpy(dst, src, count);
}
void SetRow_C(uint8* dst, uint32 v8, int count) {
#ifdef _MSC_VER
// VC will generate rep stosb.
for (int x = 0; x < count; ++x) {
dst[x] = v8;
}
#else
memset(dst, v8, count);
#endif
}
void ARGBSetRows_C(uint8* dst, uint32 v32, int width,
int dst_stride, int height) {
for (int y = 0; y < height; ++y) {
uint32* d = reinterpret_cast<uint32*>(dst);
for (int x = 0; x < width; ++x) {
d[x] = v32;
}
dst += dst_stride;
}
}
// Filter 2 rows of YUY2 UV's (422) into U and V (420).
void YUY2ToUVRow_C(const uint8* src_yuy2, int src_stride_yuy2,
uint8* dst_u, uint8* dst_v, int width) {
// Output a row of UV values, filtering 2 rows of YUY2.
for (int x = 0; x < width; x += 2) {
dst_u[0] = (src_yuy2[1] + src_yuy2[src_stride_yuy2 + 1] + 1) >> 1;
dst_v[0] = (src_yuy2[3] + src_yuy2[src_stride_yuy2 + 3] + 1) >> 1;
src_yuy2 += 4;
dst_u += 1;
dst_v += 1;
}
}
// Copy row of YUY2 UV's (422) into U and V (422).
void YUY2ToUV422Row_C(const uint8* src_yuy2,
uint8* dst_u, uint8* dst_v, int width) {
// Output a row of UV values.
for (int x = 0; x < width; x += 2) {
dst_u[0] = src_yuy2[1];
dst_v[0] = src_yuy2[3];
src_yuy2 += 4;
dst_u += 1;
dst_v += 1;
}
}
// Copy row of YUY2 Y's (422) into Y (420/422).
void YUY2ToYRow_C(const uint8* src_yuy2, uint8* dst_y, int width) {
// Output a row of Y values.
for (int x = 0; x < width - 1; x += 2) {
dst_y[x] = src_yuy2[0];
dst_y[x + 1] = src_yuy2[2];
src_yuy2 += 4;
}
if (width & 1) {
dst_y[width - 1] = src_yuy2[0];
}
}
// Filter 2 rows of UYVY UV's (422) into U and V (420).
void UYVYToUVRow_C(const uint8* src_uyvy, int src_stride_uyvy,
uint8* dst_u, uint8* dst_v, int width) {
// Output a row of UV values.
for (int x = 0; x < width; x += 2) {
dst_u[0] = (src_uyvy[0] + src_uyvy[src_stride_uyvy + 0] + 1) >> 1;
dst_v[0] = (src_uyvy[2] + src_uyvy[src_stride_uyvy + 2] + 1) >> 1;
src_uyvy += 4;
dst_u += 1;
dst_v += 1;
}
}
// Copy row of UYVY UV's (422) into U and V (422).
void UYVYToUV422Row_C(const uint8* src_uyvy,
uint8* dst_u, uint8* dst_v, int width) {
// Output a row of UV values.
for (int x = 0; x < width; x += 2) {
dst_u[0] = src_uyvy[0];
dst_v[0] = src_uyvy[2];
src_uyvy += 4;
dst_u += 1;
dst_v += 1;
}
}
// Copy row of UYVY Y's (422) into Y (420/422).
void UYVYToYRow_C(const uint8* src_uyvy, uint8* dst_y, int width) {
// Output a row of Y values.
for (int x = 0; x < width - 1; x += 2) {
dst_y[x] = src_uyvy[1];
dst_y[x + 1] = src_uyvy[3];
src_uyvy += 4;
}
if (width & 1) {
dst_y[width - 1] = src_uyvy[1];
}
}
#define BLEND(f, b, a) (((256 - a) * b) >> 8) + f
// Blend src_argb0 over src_argb1 and store to dst_argb.
// dst_argb may be src_argb0 or src_argb1.
// This code mimics the SSSE3 version for better testability.
void ARGBBlendRow_C(const uint8* src_argb0, const uint8* src_argb1,
uint8* dst_argb, int width) {
for (int x = 0; x < width - 1; x += 2) {
uint32 fb = src_argb0[0];
uint32 fg = src_argb0[1];
uint32 fr = src_argb0[2];
uint32 a = src_argb0[3];
uint32 bb = src_argb1[0];
uint32 bg = src_argb1[1];
uint32 br = src_argb1[2];
dst_argb[0] = BLEND(fb, bb, a);
dst_argb[1] = BLEND(fg, bg, a);
dst_argb[2] = BLEND(fr, br, a);
dst_argb[3] = 255u;
fb = src_argb0[4 + 0];
fg = src_argb0[4 + 1];
fr = src_argb0[4 + 2];
a = src_argb0[4 + 3];
bb = src_argb1[4 + 0];
bg = src_argb1[4 + 1];
br = src_argb1[4 + 2];
dst_argb[4 + 0] = BLEND(fb, bb, a);
dst_argb[4 + 1] = BLEND(fg, bg, a);
dst_argb[4 + 2] = BLEND(fr, br, a);
dst_argb[4 + 3] = 255u;
src_argb0 += 8;
src_argb1 += 8;
dst_argb += 8;
}
if (width & 1) {
uint32 fb = src_argb0[0];
uint32 fg = src_argb0[1];
uint32 fr = src_argb0[2];
uint32 a = src_argb0[3];
uint32 bb = src_argb1[0];
uint32 bg = src_argb1[1];
uint32 br = src_argb1[2];
dst_argb[0] = BLEND(fb, bb, a);
dst_argb[1] = BLEND(fg, bg, a);
dst_argb[2] = BLEND(fr, br, a);
dst_argb[3] = 255u;
}
}
#undef BLEND
#define ATTENUATE(f, a) (a | (a << 8)) * (f | (f << 8)) >> 24
// Multiply source RGB by alpha and store to destination.
// This code mimics the SSSE3 version for better testability.
void ARGBAttenuateRow_C(const uint8* src_argb, uint8* dst_argb, int width) {
for (int i = 0; i < width - 1; i += 2) {
uint32 b = src_argb[0];
uint32 g = src_argb[1];
uint32 r = src_argb[2];
uint32 a = src_argb[3];
dst_argb[0] = ATTENUATE(b, a);
dst_argb[1] = ATTENUATE(g, a);
dst_argb[2] = ATTENUATE(r, a);
dst_argb[3] = a;
b = src_argb[4];
g = src_argb[5];
r = src_argb[6];
a = src_argb[7];
dst_argb[4] = ATTENUATE(b, a);
dst_argb[5] = ATTENUATE(g, a);
dst_argb[6] = ATTENUATE(r, a);
dst_argb[7] = a;
src_argb += 8;
dst_argb += 8;
}
if (width & 1) {
const uint32 b = src_argb[0];
const uint32 g = src_argb[1];
const uint32 r = src_argb[2];
const uint32 a = src_argb[3];
dst_argb[0] = ATTENUATE(b, a);
dst_argb[1] = ATTENUATE(g, a);
dst_argb[2] = ATTENUATE(r, a);
dst_argb[3] = a;
}
}
#undef ATTENUATE
// Divide source RGB by alpha and store to destination.
// b = (b * 255 + (a / 2)) / a;
// g = (g * 255 + (a / 2)) / a;
// r = (r * 255 + (a / 2)) / a;
// Reciprocal method is off by 1 on some values. ie 125
// 8.8 fixed point inverse table with 1.0 in upper short and 1 / a in lower.
#define T(a) 0x01000000 + (0x10000 / a)
uint32 fixed_invtbl8[256] = {
0x01000000, 0x0100ffff, T(0x02), T(0x03), T(0x04), T(0x05), T(0x06), T(0x07),
T(0x08), T(0x09), T(0x0a), T(0x0b), T(0x0c), T(0x0d), T(0x0e), T(0x0f),
T(0x10), T(0x11), T(0x12), T(0x13), T(0x14), T(0x15), T(0x16), T(0x17),
T(0x18), T(0x19), T(0x1a), T(0x1b), T(0x1c), T(0x1d), T(0x1e), T(0x1f),
T(0x20), T(0x21), T(0x22), T(0x23), T(0x24), T(0x25), T(0x26), T(0x27),
T(0x28), T(0x29), T(0x2a), T(0x2b), T(0x2c), T(0x2d), T(0x2e), T(0x2f),
T(0x30), T(0x31), T(0x32), T(0x33), T(0x34), T(0x35), T(0x36), T(0x37),
T(0x38), T(0x39), T(0x3a), T(0x3b), T(0x3c), T(0x3d), T(0x3e), T(0x3f),
T(0x40), T(0x41), T(0x42), T(0x43), T(0x44), T(0x45), T(0x46), T(0x47),
T(0x48), T(0x49), T(0x4a), T(0x4b), T(0x4c), T(0x4d), T(0x4e), T(0x4f),
T(0x50), T(0x51), T(0x52), T(0x53), T(0x54), T(0x55), T(0x56), T(0x57),
T(0x58), T(0x59), T(0x5a), T(0x5b), T(0x5c), T(0x5d), T(0x5e), T(0x5f),
T(0x60), T(0x61), T(0x62), T(0x63), T(0x64), T(0x65), T(0x66), T(0x67),
T(0x68), T(0x69), T(0x6a), T(0x6b), T(0x6c), T(0x6d), T(0x6e), T(0x6f),
T(0x70), T(0x71), T(0x72), T(0x73), T(0x74), T(0x75), T(0x76), T(0x77),
T(0x78), T(0x79), T(0x7a), T(0x7b), T(0x7c), T(0x7d), T(0x7e), T(0x7f),
T(0x80), T(0x81), T(0x82), T(0x83), T(0x84), T(0x85), T(0x86), T(0x87),
T(0x88), T(0x89), T(0x8a), T(0x8b), T(0x8c), T(0x8d), T(0x8e), T(0x8f),
T(0x90), T(0x91), T(0x92), T(0x93), T(0x94), T(0x95), T(0x96), T(0x97),
T(0x98), T(0x99), T(0x9a), T(0x9b), T(0x9c), T(0x9d), T(0x9e), T(0x9f),
T(0xa0), T(0xa1), T(0xa2), T(0xa3), T(0xa4), T(0xa5), T(0xa6), T(0xa7),
T(0xa8), T(0xa9), T(0xaa), T(0xab), T(0xac), T(0xad), T(0xae), T(0xaf),
T(0xb0), T(0xb1), T(0xb2), T(0xb3), T(0xb4), T(0xb5), T(0xb6), T(0xb7),
T(0xb8), T(0xb9), T(0xba), T(0xbb), T(0xbc), T(0xbd), T(0xbe), T(0xbf),
T(0xc0), T(0xc1), T(0xc2), T(0xc3), T(0xc4), T(0xc5), T(0xc6), T(0xc7),
T(0xc8), T(0xc9), T(0xca), T(0xcb), T(0xcc), T(0xcd), T(0xce), T(0xcf),
T(0xd0), T(0xd1), T(0xd2), T(0xd3), T(0xd4), T(0xd5), T(0xd6), T(0xd7),
T(0xd8), T(0xd9), T(0xda), T(0xdb), T(0xdc), T(0xdd), T(0xde), T(0xdf),
T(0xe0), T(0xe1), T(0xe2), T(0xe3), T(0xe4), T(0xe5), T(0xe6), T(0xe7),
T(0xe8), T(0xe9), T(0xea), T(0xeb), T(0xec), T(0xed), T(0xee), T(0xef),
T(0xf0), T(0xf1), T(0xf2), T(0xf3), T(0xf4), T(0xf5), T(0xf6), T(0xf7),
T(0xf8), T(0xf9), T(0xfa), T(0xfb), T(0xfc), T(0xfd), T(0xfe), 0x01000100 };
#undef T
void ARGBUnattenuateRow_C(const uint8* src_argb, uint8* dst_argb, int width) {
for (int i = 0; i < width; ++i) {
uint32 b = src_argb[0];
uint32 g = src_argb[1];
uint32 r = src_argb[2];
const uint32 a = src_argb[3];
const uint32 ia = fixed_invtbl8[a] & 0xffff; // 8.8 fixed point
b = (b * ia) >> 8;
g = (g * ia) >> 8;
r = (r * ia) >> 8;
// Clamping should not be necessary but is free in assembly.
dst_argb[0] = clamp255(b);
dst_argb[1] = clamp255(g);
dst_argb[2] = clamp255(r);
dst_argb[3] = a;
src_argb += 4;
dst_argb += 4;
}
}
void ComputeCumulativeSumRow_C(const uint8* row, int32* cumsum,
const int32* previous_cumsum, int width) {
int32 row_sum[4] = {0, 0, 0, 0};
for (int x = 0; x < width; ++x) {
row_sum[0] += row[x * 4 + 0];
row_sum[1] += row[x * 4 + 1];
row_sum[2] += row[x * 4 + 2];
row_sum[3] += row[x * 4 + 3];
cumsum[x * 4 + 0] = row_sum[0] + previous_cumsum[x * 4 + 0];
cumsum[x * 4 + 1] = row_sum[1] + previous_cumsum[x * 4 + 1];
cumsum[x * 4 + 2] = row_sum[2] + previous_cumsum[x * 4 + 2];
cumsum[x * 4 + 3] = row_sum[3] + previous_cumsum[x * 4 + 3];
}
}
void CumulativeSumToAverageRow_C(const int32* tl, const int32* bl,
int w, int area, uint8* dst, int count) {
float ooa = 1.0f / area;
for (int i = 0; i < count; ++i) {
dst[0] = static_cast<uint8>((bl[w + 0] + tl[0] - bl[0] - tl[w + 0]) * ooa);
dst[1] = static_cast<uint8>((bl[w + 1] + tl[1] - bl[1] - tl[w + 1]) * ooa);
dst[2] = static_cast<uint8>((bl[w + 2] + tl[2] - bl[2] - tl[w + 2]) * ooa);
dst[3] = static_cast<uint8>((bl[w + 3] + tl[3] - bl[3] - tl[w + 3]) * ooa);
dst += 4;
tl += 4;
bl += 4;
}
}
// Copy pixels from rotated source to destination row with a slope.
LIBYUV_API
void ARGBAffineRow_C(const uint8* src_argb, int src_argb_stride,
uint8* dst_argb, const float* uv_dudv, int width) {
// Render a row of pixels from source into a buffer.
float uv[2];
uv[0] = uv_dudv[0];
uv[1] = uv_dudv[1];
for (int i = 0; i < width; ++i) {
int x = static_cast<int>(uv[0]);
int y = static_cast<int>(uv[1]);
*reinterpret_cast<uint32*>(dst_argb) =
*reinterpret_cast<const uint32*>(src_argb + y * src_argb_stride +
x * 4);
dst_argb += 4;
uv[0] += uv_dudv[2];
uv[1] += uv_dudv[3];
}
}
// C version 2x2 -> 2x1.
void InterpolateRow_C(uint8* dst_ptr, const uint8* src_ptr,
ptrdiff_t src_stride,
int width, int source_y_fraction) {
int y1_fraction = source_y_fraction;
int y0_fraction = 256 - y1_fraction;
const uint8* src_ptr1 = src_ptr + src_stride;
for (int x = 0; x < width - 1; x += 2) {
dst_ptr[0] = (src_ptr[0] * y0_fraction + src_ptr1[0] * y1_fraction) >> 8;
dst_ptr[1] = (src_ptr[1] * y0_fraction + src_ptr1[1] * y1_fraction) >> 8;
src_ptr += 2;
src_ptr1 += 2;
dst_ptr += 2;
}
if (width & 1) {
dst_ptr[0] = (src_ptr[0] * y0_fraction + src_ptr1[0] * y1_fraction) >> 8;
}
}
// Blend 2 rows into 1 for conversions such as I422ToI420.
void HalfRow_C(const uint8* src_uv, int src_uv_stride,
uint8* dst_uv, int pix) {
for (int x = 0; x < pix; ++x) {
dst_uv[x] = (src_uv[x] + src_uv[src_uv_stride + x] + 1) >> 1;
}
}
// Select 2 channels from ARGB on alternating pixels. e.g. BGBGBGBG
void ARGBToBayerRow_C(const uint8* src_argb,
uint8* dst_bayer, uint32 selector, int pix) {
int index0 = selector & 0xff;
int index1 = (selector >> 8) & 0xff;
// Copy a row of Bayer.
for (int x = 0; x < pix - 1; x += 2) {
dst_bayer[0] = src_argb[index0];
dst_bayer[1] = src_argb[index1];
src_argb += 8;
dst_bayer += 2;
}
if (pix & 1) {
dst_bayer[0] = src_argb[index0];
}
}
// Use first 4 shuffler values to reorder ARGB channels.
void ARGBShuffleRow_C(const uint8* src_argb, uint8* dst_argb,
const uint8* shuffler, int pix) {
int index0 = shuffler[0];
int index1 = shuffler[1];
int index2 = shuffler[2];
int index3 = shuffler[3];
// Shuffle a row of ARGB.
for (int x = 0; x < pix; ++x) {
// To support in-place conversion.
uint8 b = src_argb[index0];
uint8 g = src_argb[index1];
uint8 r = src_argb[index2];
uint8 a = src_argb[index3];
dst_argb[0] = b;
dst_argb[1] = g;
dst_argb[2] = r;
dst_argb[3] = a;
src_argb += 4;
dst_argb += 4;
}
}
void I422ToYUY2Row_C(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* dst_frame, int width) {
for (int x = 0; x < width - 1; x += 2) {
dst_frame[0] = src_y[0];
dst_frame[1] = src_u[0];
dst_frame[2] = src_y[1];
dst_frame[3] = src_v[0];
dst_frame += 4;
src_y += 2;
src_u += 1;
src_v += 1;
}
if (width & 1) {
dst_frame[0] = src_y[0];
dst_frame[1] = src_u[0];
dst_frame[2] = src_y[0]; // duplicate last y
dst_frame[3] = src_v[0];
}
}
void I422ToUYVYRow_C(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* dst_frame, int width) {
for (int x = 0; x < width - 1; x += 2) {
dst_frame[0] = src_u[0];
dst_frame[1] = src_y[0];
dst_frame[2] = src_v[0];
dst_frame[3] = src_y[1];
dst_frame += 4;
src_y += 2;
src_u += 1;
src_v += 1;
}
if (width & 1) {
dst_frame[0] = src_u[0];
dst_frame[1] = src_y[0];
dst_frame[2] = src_v[0];
dst_frame[3] = src_y[0]; // duplicate last y
}
}
#if !defined(LIBYUV_DISABLE_X86)
// row_win.cc has asm version, but GCC uses 2 step wrapper. 5% slower.
// TODO(fbarchard): Handle width > kMaxStride here instead of calling code.
#if defined(__x86_64__) || defined(__i386__)
void I422ToRGB565Row_SSSE3(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* rgb_buf,
int width) {
SIMD_ALIGNED(uint8 row[kMaxStride]);
I422ToARGBRow_SSSE3(src_y, src_u, src_v, row, width);
ARGBToRGB565Row_SSE2(row, rgb_buf, width);
}
#endif // defined(__x86_64__) || defined(__i386__)
#if defined(_M_IX86) || defined(__x86_64__) || defined(__i386__)
void I422ToARGB1555Row_SSSE3(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* rgb_buf,
int width) {
SIMD_ALIGNED(uint8 row[kMaxStride]);
I422ToARGBRow_SSSE3(src_y, src_u, src_v, row, width);
ARGBToARGB1555Row_SSE2(row, rgb_buf, width);
}
void I422ToARGB4444Row_SSSE3(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* rgb_buf,
int width) {
SIMD_ALIGNED(uint8 row[kMaxStride]);
I422ToARGBRow_SSSE3(src_y, src_u, src_v, row, width);
ARGBToARGB4444Row_SSE2(row, rgb_buf, width);
}
void NV12ToRGB565Row_SSSE3(const uint8* src_y,
const uint8* src_uv,
uint8* dst_rgb565,
int width) {
SIMD_ALIGNED(uint8 row[kMaxStride]);
NV12ToARGBRow_SSSE3(src_y, src_uv, row, width);
ARGBToRGB565Row_SSE2(row, dst_rgb565, width);
}
void NV21ToRGB565Row_SSSE3(const uint8* src_y,
const uint8* src_vu,
uint8* dst_rgb565,
int width) {
SIMD_ALIGNED(uint8 row[kMaxStride]);
NV21ToARGBRow_SSSE3(src_y, src_vu, row, width);
ARGBToRGB565Row_SSE2(row, dst_rgb565, width);
}
void YUY2ToARGBRow_SSSE3(const uint8* src_yuy2,
uint8* dst_argb,
int width) {
SIMD_ALIGNED(uint8 row_y[kMaxStride]);
SIMD_ALIGNED(uint8 row_u[kMaxStride / 2]);
SIMD_ALIGNED(uint8 row_v[kMaxStride / 2]);
YUY2ToUV422Row_SSE2(src_yuy2, row_u, row_v, width);
YUY2ToYRow_SSE2(src_yuy2, row_y, width);
I422ToARGBRow_SSSE3(row_y, row_u, row_v, dst_argb, width);
}
void YUY2ToARGBRow_Unaligned_SSSE3(const uint8* src_yuy2,
uint8* dst_argb,
int width) {
SIMD_ALIGNED(uint8 row_y[kMaxStride]);
SIMD_ALIGNED(uint8 row_u[kMaxStride / 2]);
SIMD_ALIGNED(uint8 row_v[kMaxStride / 2]);
YUY2ToUV422Row_Unaligned_SSE2(src_yuy2, row_u, row_v, width);
YUY2ToYRow_Unaligned_SSE2(src_yuy2, row_y, width);
I422ToARGBRow_Unaligned_SSSE3(row_y, row_u, row_v, dst_argb, width);
}
void UYVYToARGBRow_SSSE3(const uint8* src_uyvy,
uint8* dst_argb,
int width) {
SIMD_ALIGNED(uint8 row_y[kMaxStride]);
SIMD_ALIGNED(uint8 row_u[kMaxStride / 2]);
SIMD_ALIGNED(uint8 row_v[kMaxStride / 2]);
UYVYToUV422Row_SSE2(src_uyvy, row_u, row_v, width);
UYVYToYRow_SSE2(src_uyvy, row_y, width);
I422ToARGBRow_SSSE3(row_y, row_u, row_v, dst_argb, width);
}
void UYVYToARGBRow_Unaligned_SSSE3(const uint8* src_uyvy,
uint8* dst_argb,
int width) {
SIMD_ALIGNED(uint8 row_y[kMaxStride]);
SIMD_ALIGNED(uint8 row_u[kMaxStride / 2]);
SIMD_ALIGNED(uint8 row_v[kMaxStride / 2]);
UYVYToUV422Row_Unaligned_SSE2(src_uyvy, row_u, row_v, width);
UYVYToYRow_Unaligned_SSE2(src_uyvy, row_y, width);
I422ToARGBRow_Unaligned_SSSE3(row_y, row_u, row_v, dst_argb, width);
}
#endif // defined(_M_IX86) || defined(__x86_64__) || defined(__i386__)
#endif // !defined(LIBYUV_DISABLE_X86)
#undef clamp0
#undef clamp255
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif