89 lines
4.9 KiB
C
89 lines
4.9 KiB
C
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│
|
|
│vi: set et ft=c ts=4 sw=4 fenc=utf-8 :vi│
|
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
|
│ PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer │
|
|
│ Dominic Szablewski - https://phoboslab.org │
|
|
│ │
|
|
│ The MIT License(MIT) │
|
|
│ Copyright(c) 2019 Dominic Szablewski │
|
|
│ │
|
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
|
│ a copy of this software and associated documentation files(the │
|
|
│ "Software"), to deal in the Software without restriction, including │
|
|
│ without limitation the rights to use, copy, modify, merge, publish, │
|
|
│ distribute, sublicense, and / or sell copies of the Software, and to │
|
|
│ permit persons to whom the Software is furnished to do so, subject to │
|
|
│ the following conditions: │
|
|
│ │
|
|
│ The above copyright notice and this permission notice shall be │
|
|
│ included in all copies or substantial portions of the Software. │
|
|
│ │
|
|
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
|
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
|
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND │
|
|
│ NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE │
|
|
│ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN │
|
|
│ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN │
|
|
│ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE │
|
|
│ SOFTWARE. │
|
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
|
#include "dsp/mpeg/mpeg.h"
|
|
#include "libc/macros.h"
|
|
|
|
asm(".ident\t\"\\n\\n\
|
|
PL_MPEG (MIT License)\\n\
|
|
Copyright(c) 2019 Dominic Szablewski\\n\
|
|
https://phoboslab.org\"");
|
|
asm(".include \"libc/disclaimer.inc\"");
|
|
|
|
/**
|
|
* @see YCbCr2RGB() in tool/viz/lib/ycbcr2rgb.c
|
|
*/
|
|
void plm_frame_to_rgb(plm_frame_t *frame, uint8_t *rgb) {
|
|
// Chroma values are the same for each block of 4 pixels, so we proccess
|
|
// 2 lines at a time, 2 neighboring pixels each.
|
|
int w = frame->y.width, w2 = w >> 1;
|
|
int y_index1 = 0, y_index2 = w, y_next_2_lines = w + (w - frame->width);
|
|
int c_index = 0, c_next_line = w2 - (frame->width >> 1);
|
|
int rgb_index1 = 0, rgb_index2 = frame->width * 3,
|
|
rgb_next_2_lines = frame->width * 3;
|
|
int cols = frame->width >> 1, rows = frame->height >> 1;
|
|
int ccb, ccr, r, g, b;
|
|
uint8_t *y = frame->y.data, *cb = frame->cb.data, *cr = frame->cr.data;
|
|
for (int row = 0; row < rows; row++) {
|
|
for (int col = 0; col < cols; col++) {
|
|
ccb = cb[c_index];
|
|
ccr = cr[c_index];
|
|
c_index++;
|
|
r = (ccr + ((ccr * 103) >> 8)) - 179;
|
|
g = ((ccb * 88) >> 8) - 44 + ((ccr * 183) >> 8) - 91;
|
|
b = (ccb + ((ccb * 198) >> 8)) - 227;
|
|
// Line 1
|
|
int y1 = y[y_index1++];
|
|
int y2 = y[y_index1++];
|
|
rgb[rgb_index1 + 0] = MAX(0, MIN(255, y1 + r));
|
|
rgb[rgb_index1 + 1] = MAX(0, MIN(255, y1 - g));
|
|
rgb[rgb_index1 + 2] = MAX(0, MIN(255, y1 + b));
|
|
rgb[rgb_index1 + 3] = MAX(0, MIN(255, y2 + r));
|
|
rgb[rgb_index1 + 4] = MAX(0, MIN(255, y2 - g));
|
|
rgb[rgb_index1 + 5] = MAX(0, MIN(255, y2 + b));
|
|
rgb_index1 += 6;
|
|
// Line 2
|
|
int y3 = y[y_index2++];
|
|
int y4 = y[y_index2++];
|
|
rgb[rgb_index2 + 0] = MAX(0, MIN(255, y3 + r));
|
|
rgb[rgb_index2 + 1] = MAX(0, MIN(255, y3 - g));
|
|
rgb[rgb_index2 + 2] = MAX(0, MIN(255, y3 + b));
|
|
rgb[rgb_index2 + 3] = MAX(0, MIN(255, y4 + r));
|
|
rgb[rgb_index2 + 4] = MAX(0, MIN(255, y4 - g));
|
|
rgb[rgb_index2 + 5] = MAX(0, MIN(255, y4 + b));
|
|
rgb_index2 += 6;
|
|
}
|
|
y_index1 += y_next_2_lines;
|
|
y_index2 += y_next_2_lines;
|
|
rgb_index1 += rgb_next_2_lines;
|
|
rgb_index2 += rgb_next_2_lines;
|
|
c_index += c_next_line;
|
|
}
|
|
}
|