git subrepo clone https://github.com/libretro/libretro-common.git deps/libretro-common
[pcsx_rearmed.git] / deps / libretro-common / include / gfx / video_frame.h
1 /* Copyright  (C) 2010-2020 The RetroArch team
2  *
3  * ---------------------------------------------------------------------------------------
4  * The following license statement only applies to this file (video_frame.h).
5  * ---------------------------------------------------------------------------------------
6  *
7  * Permission is hereby granted, free of charge,
8  * to any person obtaining a copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
11  * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
16  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22
23 #ifndef _LIBRETRO_SDK_VIDEO_FRAME_H
24 #define _LIBRETRO_SDK_VIDEO_FRAME_H
25
26 #include <stdint.h>
27 #include <retro_common_api.h>
28 #include <retro_inline.h>
29
30 #include <gfx/scaler/scaler.h>
31
32 #include <libretro.h>
33
34 RETRO_BEGIN_DECLS
35
36 #define scaler_ctx_scale_direct(ctx, output, input) \
37 { \
38    if (ctx && ctx->unscaled && ctx->direct_pixconv) \
39       /* Just perform straight pixel conversion. */ \
40       ctx->direct_pixconv(output, input, \
41             ctx->out_width,  ctx->out_height, \
42             ctx->out_stride, ctx->in_stride); \
43    else \
44       scaler_ctx_scale(ctx, output, input); \
45 }
46
47 static INLINE void video_frame_convert_rgb16_to_rgb32(
48       struct scaler_ctx *scaler,
49       void *output,
50       const void *input,
51       int width, int height,
52       int in_pitch)
53 {
54    if (width != scaler->in_width || height != scaler->in_height)
55    {
56       scaler->in_width    = width;
57       scaler->in_height   = height;
58       scaler->out_width   = width;
59       scaler->out_height  = height;
60       scaler->in_fmt      = SCALER_FMT_RGB565;
61       scaler->out_fmt     = SCALER_FMT_ARGB8888;
62       scaler->scaler_type = SCALER_TYPE_POINT;
63       scaler_ctx_gen_filter(scaler);
64    }
65
66    scaler->in_stride  = in_pitch;
67    scaler->out_stride = width * sizeof(uint32_t);
68
69    scaler_ctx_scale_direct(scaler, output, input);
70 }
71
72 static INLINE void video_frame_scale(
73       struct scaler_ctx *scaler,
74       void *output,
75       const void *input,
76       enum scaler_pix_fmt format,
77       unsigned scaler_width,
78       unsigned scaler_height,
79       unsigned scaler_pitch,
80       unsigned width,
81       unsigned height,
82       unsigned pitch)
83 {
84    if (
85             width  != (unsigned)scaler->in_width
86          || height != (unsigned)scaler->in_height
87          || format != scaler->in_fmt
88          || pitch  != (unsigned)scaler->in_stride
89       )
90    {
91       scaler->in_fmt    = format;
92       scaler->in_width  = width;
93       scaler->in_height = height;
94       scaler->in_stride = pitch;
95
96       scaler->out_width  = scaler_width;
97       scaler->out_height = scaler_height;
98       scaler->out_stride = scaler_pitch;
99
100       scaler_ctx_gen_filter(scaler);
101    }
102
103    scaler_ctx_scale_direct(scaler, output, input);
104 }
105
106 static INLINE void video_frame_record_scale(
107       struct scaler_ctx *scaler,
108       void *output,
109       const void *input,
110       unsigned scaler_width,
111       unsigned scaler_height,
112       unsigned scaler_pitch,
113       unsigned width,
114       unsigned height,
115       unsigned pitch,
116       bool bilinear)
117 {
118    if (
119             width  != (unsigned)scaler->in_width
120          || height != (unsigned)scaler->in_height
121       )
122    {
123       scaler->in_width    = width;
124       scaler->in_height   = height;
125       scaler->in_stride   = pitch;
126
127       scaler->scaler_type = bilinear ?
128          SCALER_TYPE_BILINEAR : SCALER_TYPE_POINT;
129
130       scaler->out_width  = scaler_width;
131       scaler->out_height = scaler_height;
132       scaler->out_stride = scaler_pitch;
133
134       scaler_ctx_gen_filter(scaler);
135    }
136
137    scaler_ctx_scale_direct(scaler, output, input);
138 }
139
140 static INLINE void video_frame_convert_argb8888_to_abgr8888(
141       struct scaler_ctx *scaler,
142       void *output, const void *input,
143       int width, int height, int in_pitch)
144 {
145    if (width != scaler->in_width || height != scaler->in_height)
146    {
147       scaler->in_width    = width;
148       scaler->in_height   = height;
149       scaler->out_width   = width;
150       scaler->out_height  = height;
151       scaler->in_fmt      = SCALER_FMT_ARGB8888;
152       scaler->out_fmt     = SCALER_FMT_ABGR8888;
153       scaler->scaler_type = SCALER_TYPE_POINT;
154       scaler_ctx_gen_filter(scaler);
155    }
156
157    scaler->in_stride  = in_pitch;
158    scaler->out_stride = width * sizeof(uint32_t);
159
160    scaler_ctx_scale_direct(scaler, output, input);
161 }
162
163 static INLINE void video_frame_convert_to_bgr24(
164       struct scaler_ctx *scaler,
165       void *output, const void *input,
166       int width, int height, int in_pitch)
167 {
168    scaler->in_width    = width;
169    scaler->in_height   = height;
170    scaler->out_width   = width;
171    scaler->out_height  = height;
172    scaler->out_fmt     = SCALER_FMT_BGR24;
173    scaler->scaler_type = SCALER_TYPE_POINT;
174
175    scaler_ctx_gen_filter(scaler);
176
177    scaler->in_stride   = in_pitch;
178    scaler->out_stride  = width * 3;
179
180    scaler_ctx_scale_direct(scaler, output, input);
181 }
182
183 static INLINE void video_frame_convert_rgba_to_bgr(
184       const void *src_data,
185       void *dst_data,
186       unsigned width)
187 {
188    unsigned x;
189    uint8_t      *dst  = (uint8_t*)dst_data;
190    const uint8_t *src = (const uint8_t*)src_data;
191
192    for (x = 0; x < width; x++, dst += 3, src += 4)
193    {
194       dst[0] = src[2];
195       dst[1] = src[1];
196       dst[2] = src[0];
197    }
198 }
199
200 static INLINE bool video_pixel_frame_scale(
201       struct scaler_ctx *scaler,
202       void *output, const void *data,
203       unsigned width, unsigned height,
204       size_t pitch)
205 {
206    scaler->in_width      = width;
207    scaler->in_height     = height;
208    scaler->out_width     = width;
209    scaler->out_height    = height;
210    scaler->in_stride     = (int)pitch;
211    scaler->out_stride    = width * sizeof(uint16_t);
212
213    scaler_ctx_scale_direct(scaler, output, data);
214
215    return true;
216 }
217
218 RETRO_END_DECLS
219
220 #endif