1/*
2 *  Copyright 2011 The LibYuv Project Authors. All rights reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS. All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#ifndef INCLUDE_LIBYUV_PLANAR_FUNCTIONS_H_
12#define INCLUDE_LIBYUV_PLANAR_FUNCTIONS_H_
13
14#include "libyuv/basic_types.h"
15
16// TODO(fbarchard): Remove the following headers includes.
17#include "libyuv/convert.h"
18#include "libyuv/convert_argb.h"
19
20#ifdef __cplusplus
21namespace libyuv {
22extern "C" {
23#endif
24
25// Copy a plane of data.
26LIBYUV_API
27void CopyPlane(const uint8* src_y,
28               int src_stride_y,
29               uint8* dst_y,
30               int dst_stride_y,
31               int width,
32               int height);
33
34LIBYUV_API
35void CopyPlane_16(const uint16* src_y,
36                  int src_stride_y,
37                  uint16* dst_y,
38                  int dst_stride_y,
39                  int width,
40                  int height);
41
42// Set a plane of data to a 32 bit value.
43LIBYUV_API
44void SetPlane(uint8* dst_y,
45              int dst_stride_y,
46              int width,
47              int height,
48              uint32 value);
49
50// Split interleaved UV plane into separate U and V planes.
51LIBYUV_API
52void SplitUVPlane(const uint8* src_uv,
53                  int src_stride_uv,
54                  uint8* dst_u,
55                  int dst_stride_u,
56                  uint8* dst_v,
57                  int dst_stride_v,
58                  int width,
59                  int height);
60
61// Merge separate U and V planes into one interleaved UV plane.
62LIBYUV_API
63void MergeUVPlane(const uint8* src_u,
64                  int src_stride_u,
65                  const uint8* src_v,
66                  int src_stride_v,
67                  uint8* dst_uv,
68                  int dst_stride_uv,
69                  int width,
70                  int height);
71
72// Copy I400.  Supports inverting.
73LIBYUV_API
74int I400ToI400(const uint8* src_y,
75               int src_stride_y,
76               uint8* dst_y,
77               int dst_stride_y,
78               int width,
79               int height);
80
81#define J400ToJ400 I400ToI400
82
83// Copy I422 to I422.
84#define I422ToI422 I422Copy
85LIBYUV_API
86int I422Copy(const uint8* src_y,
87             int src_stride_y,
88             const uint8* src_u,
89             int src_stride_u,
90             const uint8* src_v,
91             int src_stride_v,
92             uint8* dst_y,
93             int dst_stride_y,
94             uint8* dst_u,
95             int dst_stride_u,
96             uint8* dst_v,
97             int dst_stride_v,
98             int width,
99             int height);
100
101// Copy I444 to I444.
102#define I444ToI444 I444Copy
103LIBYUV_API
104int I444Copy(const uint8* src_y,
105             int src_stride_y,
106             const uint8* src_u,
107             int src_stride_u,
108             const uint8* src_v,
109             int src_stride_v,
110             uint8* dst_y,
111             int dst_stride_y,
112             uint8* dst_u,
113             int dst_stride_u,
114             uint8* dst_v,
115             int dst_stride_v,
116             int width,
117             int height);
118
119// Convert YUY2 to I422.
120LIBYUV_API
121int YUY2ToI422(const uint8* src_yuy2,
122               int src_stride_yuy2,
123               uint8* dst_y,
124               int dst_stride_y,
125               uint8* dst_u,
126               int dst_stride_u,
127               uint8* dst_v,
128               int dst_stride_v,
129               int width,
130               int height);
131
132// Convert UYVY to I422.
133LIBYUV_API
134int UYVYToI422(const uint8* src_uyvy,
135               int src_stride_uyvy,
136               uint8* dst_y,
137               int dst_stride_y,
138               uint8* dst_u,
139               int dst_stride_u,
140               uint8* dst_v,
141               int dst_stride_v,
142               int width,
143               int height);
144
145LIBYUV_API
146int YUY2ToNV12(const uint8* src_yuy2,
147               int src_stride_yuy2,
148               uint8* dst_y,
149               int dst_stride_y,
150               uint8* dst_uv,
151               int dst_stride_uv,
152               int width,
153               int height);
154
155LIBYUV_API
156int UYVYToNV12(const uint8* src_uyvy,
157               int src_stride_uyvy,
158               uint8* dst_y,
159               int dst_stride_y,
160               uint8* dst_uv,
161               int dst_stride_uv,
162               int width,
163               int height);
164
165LIBYUV_API
166int YUY2ToY(const uint8* src_yuy2,
167            int src_stride_yuy2,
168            uint8* dst_y,
169            int dst_stride_y,
170            int width,
171            int height);
172
173// Convert I420 to I400. (calls CopyPlane ignoring u/v).
174LIBYUV_API
175int I420ToI400(const uint8* src_y,
176               int src_stride_y,
177               const uint8* src_u,
178               int src_stride_u,
179               const uint8* src_v,
180               int src_stride_v,
181               uint8* dst_y,
182               int dst_stride_y,
183               int width,
184               int height);
185
186// Alias
187#define J420ToJ400 I420ToI400
188#define I420ToI420Mirror I420Mirror
189
190// I420 mirror.
191LIBYUV_API
192int I420Mirror(const uint8* src_y,
193               int src_stride_y,
194               const uint8* src_u,
195               int src_stride_u,
196               const uint8* src_v,
197               int src_stride_v,
198               uint8* dst_y,
199               int dst_stride_y,
200               uint8* dst_u,
201               int dst_stride_u,
202               uint8* dst_v,
203               int dst_stride_v,
204               int width,
205               int height);
206
207// Alias
208#define I400ToI400Mirror I400Mirror
209
210// I400 mirror.  A single plane is mirrored horizontally.
211// Pass negative height to achieve 180 degree rotation.
212LIBYUV_API
213int I400Mirror(const uint8* src_y,
214               int src_stride_y,
215               uint8* dst_y,
216               int dst_stride_y,
217               int width,
218               int height);
219
220// Alias
221#define ARGBToARGBMirror ARGBMirror
222
223// ARGB mirror.
224LIBYUV_API
225int ARGBMirror(const uint8* src_argb,
226               int src_stride_argb,
227               uint8* dst_argb,
228               int dst_stride_argb,
229               int width,
230               int height);
231
232// Convert NV12 to RGB565.
233LIBYUV_API
234int NV12ToRGB565(const uint8* src_y,
235                 int src_stride_y,
236                 const uint8* src_uv,
237                 int src_stride_uv,
238                 uint8* dst_rgb565,
239                 int dst_stride_rgb565,
240                 int width,
241                 int height);
242
243// I422ToARGB is in convert_argb.h
244// Convert I422 to BGRA.
245LIBYUV_API
246int I422ToBGRA(const uint8* src_y,
247               int src_stride_y,
248               const uint8* src_u,
249               int src_stride_u,
250               const uint8* src_v,
251               int src_stride_v,
252               uint8* dst_bgra,
253               int dst_stride_bgra,
254               int width,
255               int height);
256
257// Convert I422 to ABGR.
258LIBYUV_API
259int I422ToABGR(const uint8* src_y,
260               int src_stride_y,
261               const uint8* src_u,
262               int src_stride_u,
263               const uint8* src_v,
264               int src_stride_v,
265               uint8* dst_abgr,
266               int dst_stride_abgr,
267               int width,
268               int height);
269
270// Convert I422 to RGBA.
271LIBYUV_API
272int I422ToRGBA(const uint8* src_y,
273               int src_stride_y,
274               const uint8* src_u,
275               int src_stride_u,
276               const uint8* src_v,
277               int src_stride_v,
278               uint8* dst_rgba,
279               int dst_stride_rgba,
280               int width,
281               int height);
282
283// Alias
284#define RGB24ToRAW RAWToRGB24
285
286LIBYUV_API
287int RAWToRGB24(const uint8* src_raw,
288               int src_stride_raw,
289               uint8* dst_rgb24,
290               int dst_stride_rgb24,
291               int width,
292               int height);
293
294// Draw a rectangle into I420.
295LIBYUV_API
296int I420Rect(uint8* dst_y,
297             int dst_stride_y,
298             uint8* dst_u,
299             int dst_stride_u,
300             uint8* dst_v,
301             int dst_stride_v,
302             int x,
303             int y,
304             int width,
305             int height,
306             int value_y,
307             int value_u,
308             int value_v);
309
310// Draw a rectangle into ARGB.
311LIBYUV_API
312int ARGBRect(uint8* dst_argb,
313             int dst_stride_argb,
314             int x,
315             int y,
316             int width,
317             int height,
318             uint32 value);
319
320// Convert ARGB to gray scale ARGB.
321LIBYUV_API
322int ARGBGrayTo(const uint8* src_argb,
323               int src_stride_argb,
324               uint8* dst_argb,
325               int dst_stride_argb,
326               int width,
327               int height);
328
329// Make a rectangle of ARGB gray scale.
330LIBYUV_API
331int ARGBGray(uint8* dst_argb,
332             int dst_stride_argb,
333             int x,
334             int y,
335             int width,
336             int height);
337
338// Make a rectangle of ARGB Sepia tone.
339LIBYUV_API
340int ARGBSepia(uint8* dst_argb,
341              int dst_stride_argb,
342              int x,
343              int y,
344              int width,
345              int height);
346
347// Apply a matrix rotation to each ARGB pixel.
348// matrix_argb is 4 signed ARGB values. -128 to 127 representing -2 to 2.
349// The first 4 coefficients apply to B, G, R, A and produce B of the output.
350// The next 4 coefficients apply to B, G, R, A and produce G of the output.
351// The next 4 coefficients apply to B, G, R, A and produce R of the output.
352// The last 4 coefficients apply to B, G, R, A and produce A of the output.
353LIBYUV_API
354int ARGBColorMatrix(const uint8* src_argb,
355                    int src_stride_argb,
356                    uint8* dst_argb,
357                    int dst_stride_argb,
358                    const int8* matrix_argb,
359                    int width,
360                    int height);
361
362// Deprecated. Use ARGBColorMatrix instead.
363// Apply a matrix rotation to each ARGB pixel.
364// matrix_argb is 3 signed ARGB values. -128 to 127 representing -1 to 1.
365// The first 4 coefficients apply to B, G, R, A and produce B of the output.
366// The next 4 coefficients apply to B, G, R, A and produce G of the output.
367// The last 4 coefficients apply to B, G, R, A and produce R of the output.
368LIBYUV_API
369int RGBColorMatrix(uint8* dst_argb,
370                   int dst_stride_argb,
371                   const int8* matrix_rgb,
372                   int x,
373                   int y,
374                   int width,
375                   int height);
376
377// Apply a color table each ARGB pixel.
378// Table contains 256 ARGB values.
379LIBYUV_API
380int ARGBColorTable(uint8* dst_argb,
381                   int dst_stride_argb,
382                   const uint8* table_argb,
383                   int x,
384                   int y,
385                   int width,
386                   int height);
387
388// Apply a color table each ARGB pixel but preserve destination alpha.
389// Table contains 256 ARGB values.
390LIBYUV_API
391int RGBColorTable(uint8* dst_argb,
392                  int dst_stride_argb,
393                  const uint8* table_argb,
394                  int x,
395                  int y,
396                  int width,
397                  int height);
398
399// Apply a luma/color table each ARGB pixel but preserve destination alpha.
400// Table contains 32768 values indexed by [Y][C] where 7 it 7 bit luma from
401// RGB (YJ style) and C is an 8 bit color component (R, G or B).
402LIBYUV_API
403int ARGBLumaColorTable(const uint8* src_argb,
404                       int src_stride_argb,
405                       uint8* dst_argb,
406                       int dst_stride_argb,
407                       const uint8* luma_rgb_table,
408                       int width,
409                       int height);
410
411// Apply a 3 term polynomial to ARGB values.
412// poly points to a 4x4 matrix.  The first row is constants.  The 2nd row is
413// coefficients for b, g, r and a.  The 3rd row is coefficients for b squared,
414// g squared, r squared and a squared.  The 4rd row is coefficients for b to
415// the 3, g to the 3, r to the 3 and a to the 3.  The values are summed and
416// result clamped to 0 to 255.
417// A polynomial approximation can be dirived using software such as 'R'.
418
419LIBYUV_API
420int ARGBPolynomial(const uint8* src_argb,
421                   int src_stride_argb,
422                   uint8* dst_argb,
423                   int dst_stride_argb,
424                   const float* poly,
425                   int width,
426                   int height);
427
428// Convert plane of 16 bit shorts to half floats.
429// Source values are multiplied by scale before storing as half float.
430LIBYUV_API
431int HalfFloatPlane(const uint16* src_y,
432                   int src_stride_y,
433                   uint16* dst_y,
434                   int dst_stride_y,
435                   float scale,
436                   int width,
437                   int height);
438
439// Quantize a rectangle of ARGB. Alpha unaffected.
440// scale is a 16 bit fractional fixed point scaler between 0 and 65535.
441// interval_size should be a value between 1 and 255.
442// interval_offset should be a value between 0 and 255.
443LIBYUV_API
444int ARGBQuantize(uint8* dst_argb,
445                 int dst_stride_argb,
446                 int scale,
447                 int interval_size,
448                 int interval_offset,
449                 int x,
450                 int y,
451                 int width,
452                 int height);
453
454// Copy ARGB to ARGB.
455LIBYUV_API
456int ARGBCopy(const uint8* src_argb,
457             int src_stride_argb,
458             uint8* dst_argb,
459             int dst_stride_argb,
460             int width,
461             int height);
462
463// Copy Alpha channel of ARGB to alpha of ARGB.
464LIBYUV_API
465int ARGBCopyAlpha(const uint8* src_argb,
466                  int src_stride_argb,
467                  uint8* dst_argb,
468                  int dst_stride_argb,
469                  int width,
470                  int height);
471
472// Extract the alpha channel from ARGB.
473LIBYUV_API
474int ARGBExtractAlpha(const uint8* src_argb,
475                     int src_stride_argb,
476                     uint8* dst_a,
477                     int dst_stride_a,
478                     int width,
479                     int height);
480
481// Copy Y channel to Alpha of ARGB.
482LIBYUV_API
483int ARGBCopyYToAlpha(const uint8* src_y,
484                     int src_stride_y,
485                     uint8* dst_argb,
486                     int dst_stride_argb,
487                     int width,
488                     int height);
489
490typedef void (*ARGBBlendRow)(const uint8* src_argb0,
491                             const uint8* src_argb1,
492                             uint8* dst_argb,
493                             int width);
494
495// Get function to Alpha Blend ARGB pixels and store to destination.
496LIBYUV_API
497ARGBBlendRow GetARGBBlend();
498
499// Alpha Blend ARGB images and store to destination.
500// Source is pre-multiplied by alpha using ARGBAttenuate.
501// Alpha of destination is set to 255.
502LIBYUV_API
503int ARGBBlend(const uint8* src_argb0,
504              int src_stride_argb0,
505              const uint8* src_argb1,
506              int src_stride_argb1,
507              uint8* dst_argb,
508              int dst_stride_argb,
509              int width,
510              int height);
511
512// Alpha Blend plane and store to destination.
513// Source is not pre-multiplied by alpha.
514LIBYUV_API
515int BlendPlane(const uint8* src_y0,
516               int src_stride_y0,
517               const uint8* src_y1,
518               int src_stride_y1,
519               const uint8* alpha,
520               int alpha_stride,
521               uint8* dst_y,
522               int dst_stride_y,
523               int width,
524               int height);
525
526// Alpha Blend YUV images and store to destination.
527// Source is not pre-multiplied by alpha.
528// Alpha is full width x height and subsampled to half size to apply to UV.
529LIBYUV_API
530int I420Blend(const uint8* src_y0,
531              int src_stride_y0,
532              const uint8* src_u0,
533              int src_stride_u0,
534              const uint8* src_v0,
535              int src_stride_v0,
536              const uint8* src_y1,
537              int src_stride_y1,
538              const uint8* src_u1,
539              int src_stride_u1,
540              const uint8* src_v1,
541              int src_stride_v1,
542              const uint8* alpha,
543              int alpha_stride,
544              uint8* dst_y,
545              int dst_stride_y,
546              uint8* dst_u,
547              int dst_stride_u,
548              uint8* dst_v,
549              int dst_stride_v,
550              int width,
551              int height);
552
553// Multiply ARGB image by ARGB image. Shifted down by 8. Saturates to 255.
554LIBYUV_API
555int ARGBMultiply(const uint8* src_argb0,
556                 int src_stride_argb0,
557                 const uint8* src_argb1,
558                 int src_stride_argb1,
559                 uint8* dst_argb,
560                 int dst_stride_argb,
561                 int width,
562                 int height);
563
564// Add ARGB image with ARGB image. Saturates to 255.
565LIBYUV_API
566int ARGBAdd(const uint8* src_argb0,
567            int src_stride_argb0,
568            const uint8* src_argb1,
569            int src_stride_argb1,
570            uint8* dst_argb,
571            int dst_stride_argb,
572            int width,
573            int height);
574
575// Subtract ARGB image (argb1) from ARGB image (argb0). Saturates to 0.
576LIBYUV_API
577int ARGBSubtract(const uint8* src_argb0,
578                 int src_stride_argb0,
579                 const uint8* src_argb1,
580                 int src_stride_argb1,
581                 uint8* dst_argb,
582                 int dst_stride_argb,
583                 int width,
584                 int height);
585
586// Convert I422 to YUY2.
587LIBYUV_API
588int I422ToYUY2(const uint8* src_y,
589               int src_stride_y,
590               const uint8* src_u,
591               int src_stride_u,
592               const uint8* src_v,
593               int src_stride_v,
594               uint8* dst_frame,
595               int dst_stride_frame,
596               int width,
597               int height);
598
599// Convert I422 to UYVY.
600LIBYUV_API
601int I422ToUYVY(const uint8* src_y,
602               int src_stride_y,
603               const uint8* src_u,
604               int src_stride_u,
605               const uint8* src_v,
606               int src_stride_v,
607               uint8* dst_frame,
608               int dst_stride_frame,
609               int width,
610               int height);
611
612// Convert unattentuated ARGB to preattenuated ARGB.
613LIBYUV_API
614int ARGBAttenuate(const uint8* src_argb,
615                  int src_stride_argb,
616                  uint8* dst_argb,
617                  int dst_stride_argb,
618                  int width,
619                  int height);
620
621// Convert preattentuated ARGB to unattenuated ARGB.
622LIBYUV_API
623int ARGBUnattenuate(const uint8* src_argb,
624                    int src_stride_argb,
625                    uint8* dst_argb,
626                    int dst_stride_argb,
627                    int width,
628                    int height);
629
630// Internal function - do not call directly.
631// Computes table of cumulative sum for image where the value is the sum
632// of all values above and to the left of the entry. Used by ARGBBlur.
633LIBYUV_API
634int ARGBComputeCumulativeSum(const uint8* src_argb,
635                             int src_stride_argb,
636                             int32* dst_cumsum,
637                             int dst_stride32_cumsum,
638                             int width,
639                             int height);
640
641// Blur ARGB image.
642// dst_cumsum table of width * (height + 1) * 16 bytes aligned to
643//   16 byte boundary.
644// dst_stride32_cumsum is number of ints in a row (width * 4).
645// radius is number of pixels around the center.  e.g. 1 = 3x3. 2=5x5.
646// Blur is optimized for radius of 5 (11x11) or less.
647LIBYUV_API
648int ARGBBlur(const uint8* src_argb,
649             int src_stride_argb,
650             uint8* dst_argb,
651             int dst_stride_argb,
652             int32* dst_cumsum,
653             int dst_stride32_cumsum,
654             int width,
655             int height,
656             int radius);
657
658// Multiply ARGB image by ARGB value.
659LIBYUV_API
660int ARGBShade(const uint8* src_argb,
661              int src_stride_argb,
662              uint8* dst_argb,
663              int dst_stride_argb,
664              int width,
665              int height,
666              uint32 value);
667
668// Interpolate between two images using specified amount of interpolation
669// (0 to 255) and store to destination.
670// 'interpolation' is specified as 8 bit fraction where 0 means 100% src0
671// and 255 means 1% src0 and 99% src1.
672LIBYUV_API
673int InterpolatePlane(const uint8* src0,
674                     int src_stride0,
675                     const uint8* src1,
676                     int src_stride1,
677                     uint8* dst,
678                     int dst_stride,
679                     int width,
680                     int height,
681                     int interpolation);
682
683// Interpolate between two ARGB images using specified amount of interpolation
684// Internally calls InterpolatePlane with width * 4 (bpp).
685LIBYUV_API
686int ARGBInterpolate(const uint8* src_argb0,
687                    int src_stride_argb0,
688                    const uint8* src_argb1,
689                    int src_stride_argb1,
690                    uint8* dst_argb,
691                    int dst_stride_argb,
692                    int width,
693                    int height,
694                    int interpolation);
695
696// Interpolate between two YUV images using specified amount of interpolation
697// Internally calls InterpolatePlane on each plane where the U and V planes
698// are half width and half height.
699LIBYUV_API
700int I420Interpolate(const uint8* src0_y,
701                    int src0_stride_y,
702                    const uint8* src0_u,
703                    int src0_stride_u,
704                    const uint8* src0_v,
705                    int src0_stride_v,
706                    const uint8* src1_y,
707                    int src1_stride_y,
708                    const uint8* src1_u,
709                    int src1_stride_u,
710                    const uint8* src1_v,
711                    int src1_stride_v,
712                    uint8* dst_y,
713                    int dst_stride_y,
714                    uint8* dst_u,
715                    int dst_stride_u,
716                    uint8* dst_v,
717                    int dst_stride_v,
718                    int width,
719                    int height,
720                    int interpolation);
721
722#if defined(__pnacl__) || defined(__CLR_VER) || \
723    (defined(__i386__) && !defined(__SSE2__))
724#define LIBYUV_DISABLE_X86
725#endif
726// MemorySanitizer does not support assembly code yet. http://crbug.com/344505
727#if defined(__has_feature)
728#if __has_feature(memory_sanitizer)
729#define LIBYUV_DISABLE_X86
730#endif
731#endif
732// The following are available on all x86 platforms:
733#if !defined(LIBYUV_DISABLE_X86) && \
734    (defined(_M_IX86) || defined(__x86_64__) || defined(__i386__))
735#define HAS_ARGBAFFINEROW_SSE2
736#endif
737
738// Row function for copying pixels from a source with a slope to a row
739// of destination. Useful for scaling, rotation, mirror, texture mapping.
740LIBYUV_API
741void ARGBAffineRow_C(const uint8* src_argb,
742                     int src_argb_stride,
743                     uint8* dst_argb,
744                     const float* uv_dudv,
745                     int width);
746LIBYUV_API
747void ARGBAffineRow_SSE2(const uint8* src_argb,
748                        int src_argb_stride,
749                        uint8* dst_argb,
750                        const float* uv_dudv,
751                        int width);
752
753// Shuffle ARGB channel order.  e.g. BGRA to ARGB.
754// shuffler is 16 bytes and must be aligned.
755LIBYUV_API
756int ARGBShuffle(const uint8* src_bgra,
757                int src_stride_bgra,
758                uint8* dst_argb,
759                int dst_stride_argb,
760                const uint8* shuffler,
761                int width,
762                int height);
763
764// Sobel ARGB effect with planar output.
765LIBYUV_API
766int ARGBSobelToPlane(const uint8* src_argb,
767                     int src_stride_argb,
768                     uint8* dst_y,
769                     int dst_stride_y,
770                     int width,
771                     int height);
772
773// Sobel ARGB effect.
774LIBYUV_API
775int ARGBSobel(const uint8* src_argb,
776              int src_stride_argb,
777              uint8* dst_argb,
778              int dst_stride_argb,
779              int width,
780              int height);
781
782// Sobel ARGB effect w/ Sobel X, Sobel, Sobel Y in ARGB.
783LIBYUV_API
784int ARGBSobelXY(const uint8* src_argb,
785                int src_stride_argb,
786                uint8* dst_argb,
787                int dst_stride_argb,
788                int width,
789                int height);
790
791#ifdef __cplusplus
792}  // extern "C"
793}  // namespace libyuv
794#endif
795
796#endif  // INCLUDE_LIBYUV_PLANAR_FUNCTIONS_H_
797