diff --git a/.indentignore b/.indentignore index cbbefa0427..0e5423bb85 100644 --- a/.indentignore +++ b/.indentignore @@ -1,4 +1,5 @@ subprojects/gst-plugins-bad/ext/sctp/usrsctp/usrsctplib/ +subprojects/gst-plugins-bad/sys/dwrite/libcaption/ subprojects/gstreamer-rs/ subprojects/gstreamer-rs-sys/ subprojects/gst-plugins-rs/ diff --git a/subprojects/gst-plugins-bad/sys/dwrite/libcaption/LICENSE.txt b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/LICENSE.txt new file mode 100644 index 0000000000..a770bbb560 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License + +Copyright 2016-2017 Twitch Interactive, Inc. or its affiliates. All Rights Reserved. + +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. diff --git a/subprojects/gst-plugins-bad/sys/dwrite/libcaption/caption.c b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/caption.c new file mode 100644 index 0000000000..3ceb921867 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/caption.c @@ -0,0 +1,529 @@ +/**********************************************************************************************/ +/* The MIT License */ +/* */ +/* Copyright 2016-2017 Twitch Interactive, Inc. or its affiliates. All Rights Reserved. */ +/* */ +/* 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 "caption.h" +#include "eia608.h" +#include "utf8.h" +#include "xds.h" +#include +#include +//////////////////////////////////////////////////////////////////////////////// +void +caption_frame_buffer_clear (caption_frame_buffer_t * buff) +{ + memset (buff, 0, sizeof (caption_frame_buffer_t)); +} + +void +caption_frame_state_clear (caption_frame_t * frame) +{ + frame->write = 0; + frame->timestamp = -1; + frame->state = (caption_frame_state_t) { + 0, 0, 0, SCREEN_ROWS - 1, 0, 0}; // clear global state +} + +void +caption_frame_init (caption_frame_t * frame) +{ + xds_init (&frame->xds); + caption_frame_state_clear (frame); + caption_frame_buffer_clear (&frame->back); + caption_frame_buffer_clear (&frame->front); +} + +//////////////////////////////////////////////////////////////////////////////// +// Helpers +static caption_frame_cell_t * +frame_buffer_cell (caption_frame_buffer_t * buff, int row, int col) +{ + if (!buff || 0 > row || SCREEN_ROWS <= row || 0 > col || SCREEN_COLS <= col) { + return 0; + } + + return &buff->cell[row][col]; +} + +int caption_frame_clear_char (caption_frame_t * frame, int row, int col) +{ + if (!frame->write) { + return 0; + } + + caption_frame_cell_t *cell = frame_buffer_cell (frame->write, row, col); + + if (cell) { + memset (cell, 0, sizeof (caption_frame_cell_t)); + return 1; + } + + return 0; +} + +uint16_t _eia608_from_utf8 (const char *s); // function is in eia608.c.re2c +int +caption_frame_write_char (caption_frame_t * frame, int row, int col, + eia608_style_t style, int underline, const char *c) +{ + if (!frame->write || !_eia608_from_utf8 (c)) { + return 0; + } + + caption_frame_cell_t *cell = frame_buffer_cell (frame->write, row, col); + + if (cell && utf8_char_copy (&cell->data[0], c)) { + cell->uln = underline; + cell->sty = style; + return 1; + } + + return 0; +} + +const utf8_char_t * +caption_frame_read_char (caption_frame_t * frame, int row, int col, + eia608_style_t * style, int *underline) +{ + // always read from front + caption_frame_cell_t *cell = frame_buffer_cell (&frame->front, row, col); + + if (!cell) { + if (style) { + (*style) = eia608_style_white; + } + + if (underline) { + (*underline) = 0; + } + + return EIA608_CHAR_NULL; + } + + if (style) { + (*style) = cell->sty; + } + + if (underline) { + (*underline) = cell->uln; + } + + return &cell->data[0]; +} + +//////////////////////////////////////////////////////////////////////////////// +// Parsing +libcaption_stauts_t +caption_frame_carriage_return (caption_frame_t * frame) +{ + if (0 > frame->state.row || SCREEN_ROWS <= frame->state.row) { + return LIBCAPTION_ERROR; + } + + int r = frame->state.row - (frame->state.rup - 1); + + if (0 >= r || !caption_frame_rollup (frame)) { + return LIBCAPTION_OK; + } + + for (; r < SCREEN_ROWS; ++r) { + uint8_t *dst = (uint8_t *) frame_buffer_cell (frame->write, r - 1, 0); + uint8_t *src = (uint8_t *) frame_buffer_cell (frame->write, r - 0, 0); + memcpy (dst, src, sizeof (caption_frame_cell_t) * SCREEN_COLS); + } + + frame->state.col = 0; + caption_frame_cell_t *cell = + frame_buffer_cell (frame->write, SCREEN_ROWS - 1, 0); + memset (cell, 0, sizeof (caption_frame_cell_t) * SCREEN_COLS); + return LIBCAPTION_OK; +} + +//////////////////////////////////////////////////////////////////////////////// +libcaption_stauts_t +eia608_write_char (caption_frame_t * frame, char *c) +{ + if (0 == c || 0 == c[0] || SCREEN_ROWS <= frame->state.row + || 0 > frame->state.row || SCREEN_COLS <= frame->state.col + || 0 > frame->state.col) { + // NO-OP + } else if (caption_frame_write_char (frame, frame->state.row, + frame->state.col, frame->state.sty, frame->state.uln, c)) { + frame->state.col += 1; + } + + return LIBCAPTION_OK; +} + +libcaption_stauts_t +caption_frame_end (caption_frame_t * frame) +{ + memcpy (&frame->front, &frame->back, sizeof (caption_frame_buffer_t)); + caption_frame_buffer_clear (&frame->back); // This is required + return LIBCAPTION_READY; +} + +libcaption_stauts_t +caption_frame_decode_preamble (caption_frame_t * frame, uint16_t cc_data) +{ + eia608_style_t sty; + int row, col, chn, uln; + + if (eia608_parse_preamble (cc_data, &row, &col, &sty, &chn, &uln)) { + frame->state.row = row; + frame->state.col = col; + frame->state.sty = sty; + frame->state.uln = uln; + } + + return LIBCAPTION_OK; +} + +libcaption_stauts_t +caption_frame_decode_midrowchange (caption_frame_t * frame, uint16_t cc_data) +{ + eia608_style_t sty; + int chn, unl; + + if (eia608_parse_midrowchange (cc_data, &chn, &sty, &unl)) { + frame->state.sty = sty; + frame->state.uln = unl; + } + + return LIBCAPTION_OK; +} + +libcaption_stauts_t +caption_frame_backspace (caption_frame_t * frame) +{ + // do not reverse wrap (tw 28:20) + frame->state.col = (0 < frame->state.col) ? (frame->state.col - 1) : 0; + caption_frame_clear_char (frame, frame->state.row, frame->state.col); + return LIBCAPTION_READY; +} + +libcaption_stauts_t +caption_frame_delete_to_end_of_row (caption_frame_t * frame) +{ + int c; + if (frame->write) { + for (c = frame->state.col; c < SCREEN_COLS; ++c) { + caption_frame_clear_char (frame, frame->state.row, c); + } + } + // TODO test this and replace loop + // uint8_t* dst = (uint8_t*)frame_buffer_cell(frame->write, frame->state.row, frame->state.col); + // memset(dst,0,sizeof(caption_frame_cell_t) * (SCREEN_COLS - frame->state.col - 1)) + + return LIBCAPTION_READY; +} + +libcaption_stauts_t +caption_frame_decode_control (caption_frame_t * frame, uint16_t cc_data) +{ + int cc; + eia608_control_t cmd = eia608_parse_control (cc_data, &cc); + + switch (cmd) { + // PAINT ON + case eia608_control_resume_direct_captioning: + frame->state.rup = 0; + frame->write = &frame->front; + return LIBCAPTION_OK; + + case eia608_control_erase_display_memory: + caption_frame_buffer_clear (&frame->front); + return LIBCAPTION_CLEAR; + + // ROLL-UP + case eia608_control_roll_up_2: + frame->state.rup = 1; + frame->write = &frame->front; + return LIBCAPTION_OK; + + case eia608_control_roll_up_3: + frame->state.rup = 2; + frame->write = &frame->front; + return LIBCAPTION_OK; + + case eia608_control_roll_up_4: + frame->state.rup = 3; + frame->write = &frame->front; + return LIBCAPTION_OK; + + case eia608_control_carriage_return: + return caption_frame_carriage_return (frame); + + // Corrections (Is this only valid as part of paint on?) + case eia608_control_backspace: + return caption_frame_backspace (frame); + case eia608_control_delete_to_end_of_row: + return caption_frame_delete_to_end_of_row (frame); + + // POP ON + case eia608_control_resume_caption_loading: + frame->state.rup = 0; + frame->write = &frame->back; + return LIBCAPTION_OK; + + case eia608_control_erase_non_displayed_memory: + caption_frame_buffer_clear (&frame->back); + return LIBCAPTION_OK; + + case eia608_control_end_of_caption: + return caption_frame_end (frame); + + // cursor positioning + case eia608_tab_offset_0: + case eia608_tab_offset_1: + case eia608_tab_offset_2: + case eia608_tab_offset_3: + frame->state.col += (cmd - eia608_tab_offset_0); + return LIBCAPTION_OK; + + // Unhandled + default: + case eia608_control_alarm_off: + case eia608_control_alarm_on: + case eia608_control_text_restart: + case eia608_control_text_resume_text_display: + return LIBCAPTION_OK; + } +} + +libcaption_stauts_t +caption_frame_decode_text (caption_frame_t * frame, uint16_t cc_data) +{ + int chan; + char char1[5], char2[5]; + size_t chars = eia608_to_utf8 (cc_data, &chan, &char1[0], &char2[0]); + + if (eia608_is_westeu (cc_data)) { + // Extended charcters replace the previous charcter for back compatibility + caption_frame_backspace (frame); + } + + if (0 < chars) { + eia608_write_char (frame, char1); + } + + if (1 < chars) { + eia608_write_char (frame, char2); + } + + return LIBCAPTION_OK; +} + +libcaption_stauts_t +caption_frame_decode (caption_frame_t * frame, uint16_t cc_data, + double timestamp) +{ + if (!eia608_parity_varify (cc_data)) { + frame->status = LIBCAPTION_ERROR; + return frame->status; + } + + if (eia608_is_padding (cc_data)) { + frame->status = LIBCAPTION_OK; + return frame->status; + } + + // skip duplicate controll commands. We also skip duplicate specialna to match the behaviour of iOS/vlc + if ((eia608_is_specialna(cc_data) || eia608_is_control(cc_data)) && cc_data == frame->state.cc_data) { + if (timestamp < 0 && caption_frame_popon (frame)) + frame->timestamp += (1 / 29.97); + return LIBCAPTION_OK; + } + + if (timestamp >= 0) { + frame->timestamp = timestamp; + frame->status = LIBCAPTION_OK; + } else if (caption_frame_popon (frame)) { + frame->timestamp += (1 / 29.97); + } + + frame->state.cc_data = cc_data; + + if (frame->xds.state) { + frame->status = xds_decode (&frame->xds, cc_data); + } else if (eia608_is_xds (cc_data)) { + frame->status = xds_decode (&frame->xds, cc_data); + } else if (eia608_is_control (cc_data)) { + frame->status = caption_frame_decode_control (frame, cc_data); + } else if (eia608_is_basicna (cc_data) || eia608_is_specialna (cc_data) + || eia608_is_westeu (cc_data)) { + + // Don't decode text if we dont know what mode we are in. + if (!frame->write) { + frame->status = LIBCAPTION_OK; + return frame->status; + } + + frame->status = caption_frame_decode_text (frame, cc_data); + + // If we are in paint on mode, display immiditally + if (LIBCAPTION_OK == frame->status && caption_frame_painton (frame)) { + frame->status = LIBCAPTION_READY; + } + } else if (eia608_is_preamble (cc_data)) { + frame->status = caption_frame_decode_preamble (frame, cc_data); + } else if (eia608_is_midrowchange (cc_data)) { + frame->status = caption_frame_decode_midrowchange (frame, cc_data); + } + + return frame->status; +} + +//////////////////////////////////////////////////////////////////////////////// +int +caption_frame_from_text (caption_frame_t * frame, const utf8_char_t * data) +{ + ssize_t size = (ssize_t) strlen (data); + caption_frame_init (frame); + frame->write = &frame->back; + + for (size_t r = 0; (*data) && size && r < SCREEN_ROWS;) { + // skip whitespace at start of line + while (size && utf8_char_whitespace (data)) { + size_t s = utf8_char_length (data); + data += s, size -= s; + } + + // get charcter count for wrap (or orest of line) + utf8_size_t char_count = utf8_wrap_length (data, SCREEN_COLS); + // write to caption frame + for (size_t c = 0; c < char_count; ++c) { + size_t char_length = utf8_char_length (data); + caption_frame_write_char (frame, r, c, eia608_style_white, 0, data); + data += char_length, size -= char_length; + } + + r += char_count ? 1 : 0; // Update row num only if not blank + } + + caption_frame_end (frame); + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +size_t +caption_frame_to_text (caption_frame_t * frame, utf8_char_t * data, int full) +{ + int r, c, uln, crlf = 0, count = 0; + size_t s, size = 0; + eia608_style_t sty; + (*data) = '\0'; + + for (r = 0; r < SCREEN_ROWS; ++r) { + crlf += count, count = 0; + for (c = 0; c < SCREEN_COLS; ++c) { + const utf8_char_t *chr = + caption_frame_read_char (frame, r, c, &sty, &uln); + // dont start a new line until we encounter at least one printable character + if (full || + (0 < utf8_char_length (chr) && (0 < count + || !utf8_char_whitespace (chr)))) { + if (0 < crlf) { + memcpy (data, "\r\n\0", 3); + data += 2, size += 2, crlf = 0; + } + + s = utf8_char_copy (data, chr); + data += s, size += s, ++count; + } + } + } + + return size; +} + +//////////////////////////////////////////////////////////////////////////////// +size_t +caption_frame_dump_buffer (caption_frame_t * frame, utf8_char_t * buf) +{ + int r, c; + size_t bytes, total = 0; + bytes = + sprintf (buf, + " timestamp: %f\n row: %02d col: %02d roll-up: %d\n", + frame->timestamp, frame->state.row, frame->state.col, + caption_frame_rollup (frame)); + total += bytes, buf += bytes; + bytes = + sprintf (buf, + " 00000000001111111111222222222233\t 00000000001111111111222222222233\n" + " 01234567890123456789012345678901\t 01234567890123456789012345678901\n" + " %s--------------------------------%s\t %s--------------------------------%s\n", + EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_RIGHT, + EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_LEFT, + EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_RIGHT, + EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_LEFT); + total += bytes; + buf += bytes; + + for (r = 0; r < SCREEN_ROWS; ++r) { + bytes = sprintf (buf, "%02d%s", r, EIA608_CHAR_VERTICAL_LINE); + total += bytes, buf += bytes; + + // front buffer + for (c = 0; c < SCREEN_COLS; ++c) { + caption_frame_cell_t *cell = frame_buffer_cell (&frame->front, r, c); + bytes = utf8_char_copy (buf, (!cell + || 0 == cell->data[0]) ? EIA608_CHAR_SPACE : &cell->data[0]); + total += bytes, buf += bytes; + } + + bytes = + sprintf (buf, "%s\t%02d%s", EIA608_CHAR_VERTICAL_LINE, r, + EIA608_CHAR_VERTICAL_LINE); + total += bytes, buf += bytes; + + // back buffer + for (c = 0; c < SCREEN_COLS; ++c) { + caption_frame_cell_t *cell = frame_buffer_cell (&frame->back, r, c); + bytes = utf8_char_copy (buf, (!cell + || 0 == cell->data[0]) ? EIA608_CHAR_SPACE : &cell->data[0]); + total += bytes, buf += bytes; + } + + bytes = sprintf (buf, "%s\n", EIA608_CHAR_VERTICAL_LINE); + total += bytes, buf += bytes; + } + + bytes = + sprintf (buf, + " %s--------------------------------%s\t %s--------------------------------%s\n", + EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_RIGHT, + EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_LEFT, + EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_RIGHT, + EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_LEFT); + total += bytes, buf += bytes; + return total; +} + +void +caption_frame_dump (caption_frame_t * frame) +{ + utf8_char_t buff[CAPTION_FRAME_DUMP_BUF_SIZE]; + caption_frame_dump_buffer (frame, buff); + fprintf (stderr, "%s\n", buff); +} diff --git a/subprojects/gst-plugins-bad/sys/dwrite/libcaption/caption.h b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/caption.h new file mode 100644 index 0000000000..b66cab06c1 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/caption.h @@ -0,0 +1,136 @@ +/**********************************************************************************************/ +/* The MIT License */ +/* */ +/* Copyright 2016-2017 Twitch Interactive, Inc. or its affiliates. All Rights Reserved. */ +/* */ +/* 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. */ +/**********************************************************************************************/ +#ifndef LIBCAPTION_H +#define LIBCAPTION_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "eia608.h" +#include "utf8.h" +#include "xds.h" + +typedef enum { + LIBCAPTION_ERROR = 0, + LIBCAPTION_OK = 1, + LIBCAPTION_READY = 2, + LIBCAPTION_CLEAR = 3, +} libcaption_stauts_t; + +static inline libcaption_stauts_t libcaption_status_update(libcaption_stauts_t old_stat, libcaption_stauts_t new_stat) +{ + return (LIBCAPTION_ERROR == old_stat || LIBCAPTION_ERROR == new_stat) ? LIBCAPTION_ERROR : (LIBCAPTION_READY == old_stat) ? LIBCAPTION_READY : new_stat; +} + +#define SCREEN_ROWS 15 +#define SCREEN_COLS 32 + +typedef struct { + uint8_t uln; //< underline + uint8_t sty; //< style + utf8_char_t data[5]; //< 4 byte utf8 values plus null term +} caption_frame_cell_t; + +typedef struct { + caption_frame_cell_t cell[SCREEN_ROWS][SCREEN_COLS]; +} caption_frame_buffer_t; + +typedef struct { + uint8_t uln; //< underline + uint8_t sty; //< style + uint8_t rup; //< roll-up line count minus 1 + int8_t row, col; + uint16_t cc_data; +} caption_frame_state_t; + +// timestamp and duration are in seconds +typedef struct { + double timestamp; + xds_t xds; + caption_frame_state_t state; + caption_frame_buffer_t front; + caption_frame_buffer_t back; + caption_frame_buffer_t* write; + libcaption_stauts_t status; +} caption_frame_t; + +/*! + \brief Initializes an allocated caption_frame_t instance + \param frame Pointer to prealocated caption_frame_t object +*/ +void caption_frame_init(caption_frame_t* frame); +/*! \brief + \param +*/ +static inline int caption_frame_popon(caption_frame_t* frame) { return (frame->write == &frame->back) ? 1 : 0; } +/*! \brief + \param +*/ +static inline int caption_frame_painton(caption_frame_t* frame) { return (frame->write == &frame->front) ? 1 : 0; } +/*! \brief + \param +*/ +const static int _caption_frame_rollup[] = { 0, 2, 3, 4 }; +static inline int caption_frame_rollup(caption_frame_t* frame) { return _caption_frame_rollup[frame->state.rup]; } +/*! \brief + \param +*/ +static inline double caption_frame_timestamp(caption_frame_t* frame) { return frame->timestamp; } +/*! \brief Writes a single charcter to a caption_frame_t object + \param frame A pointer to an allocted and initialized caption_frame_t object + \param row Row position to write charcter, must be between 0 and SCREEN_ROWS-1 + \param col Column position to write charcter, must be between 0 and SCREEN_ROWS-1 + \param style Style to apply to charcter + \param underline Set underline attribute, 0 = off any other value = on + \param c pointer to a single valid utf8 charcter. Bytes are automatically determined, and a NULL terminator is not required +*/ +int caption_frame_write_char(caption_frame_t* frame, int row, int col, eia608_style_t style, int underline, const utf8_char_t* c); +/*! \brief + \param +*/ +const utf8_char_t* caption_frame_read_char(caption_frame_t* frame, int row, int col, eia608_style_t* style, int* underline); +/*! \brief + \param +*/ +libcaption_stauts_t caption_frame_decode(caption_frame_t* frame, uint16_t cc_data, double timestamp); +/*! \brief + \param +*/ +int caption_frame_from_text(caption_frame_t* frame, const utf8_char_t* data); +/*! \brief + \param +*/ +#define CAPTION_FRAME_TEXT_BYTES (4 * ((SCREEN_COLS + 2) * SCREEN_ROWS) + 1) +size_t caption_frame_to_text(caption_frame_t* frame, utf8_char_t* data, int full); +/*! \brief + \param +*/ +#define CAPTION_FRAME_DUMP_BUF_SIZE 8192 +size_t caption_frame_dump_buffer(caption_frame_t* frame, utf8_char_t* buf); +void caption_frame_dump(caption_frame_t* frame); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/subprojects/gst-plugins-bad/sys/dwrite/libcaption/eia608.c b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/eia608.c new file mode 100644 index 0000000000..078d55bb3b --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/eia608.c @@ -0,0 +1,375 @@ +/**********************************************************************************************/ +/* The MIT License */ +/* */ +/* Copyright 2016-2017 Twitch Interactive, Inc. or its affiliates. All Rights Reserved. */ +/* */ +/* 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 "eia608.h" +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////// +int eia608_row_map[] = { 10, -1, 0, 1, 2, 3, 11, 12, 13, 14, 4, 5, 6, 7, 8, 9 }; +int eia608_reverse_row_map[] = + { 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 0, 6, 7, 8, 9, 1 }; + +const char *eia608_style_map[] = { + "white", + "green", + "blue", + "cyan", + "red", + "yellow", + "magenta", + "italics", +}; + +static inline uint16_t +eia608_row_pramble (int row, int chan, int x, int underline) +{ + row = eia608_reverse_row_map[row & 0x0F]; + return eia608_parity (0x1040 | (chan ? 0x0800 : 0x0000) | ((row << 7) & + 0x0700) | ((row << 5) & 0x0020) | ((x << 1) & 0x001E) | (underline ? + 0x0001 : 0x0000)); +} + +uint16_t +eia608_row_column_pramble (int row, int col, int chan, int underline) +{ + return eia608_row_pramble (row, chan, 0x8 | (col / 4), underline); +} + +uint16_t +eia608_row_style_pramble (int row, int chan, eia608_style_t style, + int underline) +{ + return eia608_row_pramble (row, chan, style, underline); +} + +uint16_t +eia608_midrow_change (int chan, eia608_style_t style, int underline) +{ + return eia608_parity (0x1120 | ((chan << 11) & 0x0800) | ((style << 1) & + 0x000E) | (underline & 0x0001)); +} + +int +eia608_parse_preamble (uint16_t cc_data, int *row, int *col, + eia608_style_t * style, int *chan, int *underline) +{ + (*row) = + eia608_row_map[((0x0700 & cc_data) >> 7) | ((0x0020 & cc_data) >> 5)]; + (*chan) = ! !(0x0800 & cc_data); + (*underline) = 0x0001 & cc_data; + + if (0x0010 & cc_data) { + (*style) = eia608_style_white; + (*col) = 4 * ((0x000E & cc_data) >> 1); + } else { + (*style) = (0x000E & cc_data) >> 1; + (*col) = 0; + } + + return 1; +} + +int +eia608_parse_midrowchange (uint16_t cc_data, int *chan, eia608_style_t * style, + int *underline) +{ + (*chan) = ! !(0x0800 & cc_data); + + if (0x1120 == (0x7770 & cc_data)) { + (*style) = (0x000E & cc_data) >> 1; + (*underline) = 0x0001 & cc_data; + } + + return 1; +} + +//////////////////////////////////////////////////////////////////////////////// +// control command +eia608_control_t +eia608_parse_control (uint16_t cc_data, int *cc) +{ + if (0x0200 & cc_data) { + (*cc) = (cc_data & 0x0800 ? 0x01 : 0x00); + return (eia608_control_t) (0x177F & cc_data); + } else { + (*cc) = (cc_data & 0x0800 ? 0x01 : 0x00) | (cc_data & 0x0100 ? 0x02 : 0x00); + return (eia608_control_t) (0x167F & cc_data); + } +} + +uint16_t +eia608_control_command (eia608_control_t cmd, int cc) +{ + uint16_t c = (cc & 0x01) ? 0x0800 : 0x0000; + uint16_t f = (cc & 0x02) ? 0x0100 : 0x0000; + + if (eia608_tab_offset_0 == (eia608_control_t) (cmd & 0xFFC0)) { + return (eia608_control_t) eia608_parity (cmd | c); + } else { + return (eia608_control_t) eia608_parity (cmd | c | f); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// text +static const char * +utf8_from_index (int idx) +{ + return (0 <= idx && EIA608_CHAR_COUNT > idx) ? eia608_char_map[idx] : ""; +} + +static int +eia608_to_index (uint16_t cc_data, int *chan, int *c1, int *c2) +{ + (*c1) = (*c2) = -1; + (*chan) = 0; + cc_data &= 0x7F7F; // strip off parity bits + + // Handle Basic NA BEFORE we strip the channel bit + if (eia608_is_basicna (cc_data)) { + // we got first char, yes. But what about second char? + (*c1) = (cc_data >> 8) - 0x20; + cc_data &= 0x00FF; + + if (0x0020 <= cc_data && 0x0080 > cc_data) { + (*c2) = cc_data - 0x20; + return 2; + } + + return 1; + } + // Check then strip second channel toggle + (*chan) = cc_data & 0x0800; + cc_data = cc_data & 0xF7FF; + + if (eia608_is_specialna (cc_data)) { + // Special North American character + (*c1) = cc_data - 0x1130 + 0x60; + return 1; + } + + if (0x1220 <= cc_data && 0x1240 > cc_data) { + // Extended Western European character set, Spanish/Miscellaneous/French + (*c1) = cc_data - 0x1220 + 0x70; + return 1; + } + + if (0x1320 <= cc_data && 0x1340 > cc_data) { + // Extended Western European character set, Portuguese/German/Danish + (*c1) = cc_data - 0x1320 + 0x90; + return 1; + } + + return 0; +} + +int +eia608_to_utf8 (uint16_t c, int *chan, char *str1, char *str2) +{ + int c1, c2; + int size = (int) eia608_to_index (c, chan, &c1, &c2); + utf8_char_copy (str1, utf8_from_index (c1)); + utf8_char_copy (str2, utf8_from_index (c2)); + return size; +} + +uint16_t +eia608_from_basicna (uint16_t bna1, uint16_t bna2) +{ + if (!eia608_is_basicna (bna1) || !eia608_is_basicna (bna2)) { + return 0; + } + + return eia608_parity ((0xFF00 & bna1) | ((0xFF00 & bna2) >> 8)); +} + +// prototype for re2c generated function +uint16_t _eia608_from_utf8 (const utf8_char_t * s); +uint16_t +eia608_from_utf8_1 (const utf8_char_t * c, int chan) +{ + uint16_t cc_data = _eia608_from_utf8 (c); + + if (0 == cc_data) { + return cc_data; + } + + if (chan && !eia608_is_basicna (cc_data)) { + cc_data |= 0x0800; + } + + return eia608_parity (cc_data); +} + +uint16_t +eia608_from_utf8_2 (const utf8_char_t * c1, const utf8_char_t * c2) +{ + uint16_t cc1 = _eia608_from_utf8 (c1); + uint16_t cc2 = _eia608_from_utf8 (c2); + return eia608_from_basicna (cc1, cc2); +} + +//////////////////////////////////////////////////////////////////////////////// + +int +eia608_to_text (char *buf, ssize_t size, uint16_t cc_data) +{ + eia608_style_t style; + const char *text = 0; + char char1[5], char2[5]; + char1[0] = char2[0] = 0; + int row, col, chan, underline; + int ret; + + if (!eia608_parity_varify (cc_data)) { + text = "parity failed"; + } else if (0 == eia608_parity_strip (cc_data)) { + text = "pad"; + } else if (eia608_is_basicna (cc_data)) { + text = "basicna"; + eia608_to_utf8 (cc_data, &chan, &char1[0], &char2[0]); + } else if (eia608_is_specialna (cc_data)) { + text = "specialna"; + eia608_to_utf8 (cc_data, &chan, &char1[0], &char2[0]); + } else if (eia608_is_westeu (cc_data)) { + text = "westeu"; + eia608_to_utf8 (cc_data, &chan, &char1[0], &char2[0]); + } else if (eia608_is_xds (cc_data)) { + text = "xds"; + } else if (eia608_is_midrowchange (cc_data)) { + text = "midrowchange"; + } else if (eia608_is_norpak (cc_data)) { + text = "norpak"; + } else if (eia608_is_preamble (cc_data)) { + eia608_parse_preamble (cc_data, &row, &col, &style, &chan, &underline); + ret = snprintf(buf, size, "cc %04X (%04X) '%s' '%s' (preamble: row: %d col: %d style: %d chan: %d underline: %d)", + cc_data, eia608_parity_strip (cc_data), char1, char2, row, col, style, chan, underline); + } else if (eia608_is_control (cc_data)) { + switch (eia608_parse_control (cc_data, &chan)) { + + default: + text = "unknown_control"; + break; + + case eia608_tab_offset_0: + text = "eia608_tab_offset_0"; + break; + + case eia608_tab_offset_1: + text = "eia608_tab_offset_1"; + break; + + case eia608_tab_offset_2: + text = "eia608_tab_offset_2"; + break; + + case eia608_tab_offset_3: + text = "eia608_tab_offset_3"; + break; + + case eia608_control_resume_caption_loading: + text = "eia608_control_resume_caption_loading"; + break; + + case eia608_control_backspace: + text = "eia608_control_backspace"; + break; + + case eia608_control_alarm_off: + text = "eia608_control_alarm_off"; + break; + + case eia608_control_alarm_on: + text = "eia608_control_alarm_on"; + break; + + case eia608_control_delete_to_end_of_row: + text = "eia608_control_delete_to_end_of_row"; + break; + + case eia608_control_roll_up_2: + text = "eia608_control_roll_up_2"; + break; + + case eia608_control_roll_up_3: + text = "eia608_control_roll_up_3"; + break; + + case eia608_control_roll_up_4: + text = "eia608_control_roll_up_4"; + break; + + case eia608_control_resume_direct_captioning: + text = "eia608_control_resume_direct_captioning"; + break; + + case eia608_control_text_restart: + text = "eia608_control_text_restart"; + break; + + case eia608_control_text_resume_text_display: + text = "eia608_control_text_resume_text_display"; + break; + + case eia608_control_erase_display_memory: + text = "eia608_control_erase_display_memory"; + break; + + case eia608_control_carriage_return: + text = "eia608_control_carriage_return"; + break; + + case eia608_control_erase_non_displayed_memory: + text = "eia608_control_erase_non_displayed_memory"; + break; + + case eia608_control_end_of_caption: + text = "eia608_control_end_of_caption"; + break; + } + } else { + text = "unhandled"; + } + + if (text != 0) { + ret = snprintf (buf, size, "cc %04X (%04X) '%s' '%s' (%s)", cc_data, eia608_parity_strip (cc_data), char1, char2, text); + } + + return ret; +} + +void +eia608_dump (uint16_t cc_data) +{ + char *text = NULL; + int bufsz; + + bufsz = eia608_to_text (NULL, 0, cc_data); + text = malloc(bufsz + 1); + eia608_to_text (text, bufsz + 1, cc_data); + fprintf (stderr, "%s\n", text); + + free (text); +} diff --git a/subprojects/gst-plugins-bad/sys/dwrite/libcaption/eia608.h b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/eia608.h new file mode 100644 index 0000000000..48a47a7058 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/eia608.h @@ -0,0 +1,219 @@ +/**********************************************************************************************/ +/* The MIT License */ +/* */ +/* Copyright 2016-2017 Twitch Interactive, Inc. or its affiliates. All Rights Reserved. */ +/* */ +/* 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. */ +/**********************************************************************************************/ +#ifndef LIBCAPTION_EIA608_H +#define LIBCAPTION_EIA608_H +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "eia608_charmap.h" +#include "utf8.h" +//////////////////////////////////////////////////////////////////////////////// +// Parity +#define EIA608_BX(B, X) (((B) << (X)) & 0x80) +#define EIA608_BP(B) ((B)&0x7F) | (0x80 ^ EIA608_BX((B), 1) ^ EIA608_BX((B), 2) ^ EIA608_BX((B), 3) ^ EIA608_BX((B), 4) ^ EIA608_BX((B), 5) ^ EIA608_BX((B), 6) ^ EIA608_BX((B), 7)) +#define EIA608_B2(B) EIA608_BP((B) + 0), EIA608_BP((B) + 1), EIA608_BP((B) + 2), EIA608_BP((B) + 3), EIA608_BP((B) + 4), EIA608_BP((B) + 5), EIA608_BP((B) + 6), EIA608_BP((B) + 7) +#define EIA608_B1(B) EIA608_B2((B) + 0), EIA608_B2((B) + 8), EIA608_B2((B) + 16), EIA608_B2((B) + 24), EIA608_B2((B) + 32), EIA608_B2((B) + 40), EIA608_B2((B) + 48), EIA608_B2((B) + 56) + +static const uint8_t eia608_parity_table[] = { EIA608_B1(0), EIA608_B1(64) }; +extern const char* eia608_style_map[]; + +#ifdef _MSC_VER +#ifndef inline +#define inline __inline +#endif +// ssize_t is POSIX and does not exist on Windows +#if defined(_WIN64) +typedef signed long ssize_t; +#else +typedef signed int ssize_t; +#endif +#endif + +/*! \brief + \param +*/ +static inline uint8_t eia608_parity_byte(uint8_t cc_data) { return eia608_parity_table[0x7F & cc_data]; } +/*! \brief + \param +*/ +static inline uint16_t eia608_parity_word(uint16_t cc_data) { return (uint16_t)((eia608_parity_byte((uint8_t)(cc_data >> 8)) << 8) | eia608_parity_byte((uint8_t)cc_data)); } +/*! \brief + \param +*/ +static inline uint16_t eia608_parity(uint16_t cc_data) { return eia608_parity_word(cc_data); } +/*! \brief + \param +*/ +static inline int eia608_parity_varify(uint16_t cc_data) { return eia608_parity_word(cc_data) == cc_data ? 1 : 0; } +/*! \brief + \param +*/ +static inline int eia608_parity_strip(uint16_t cc_data) { return cc_data & 0x7F7F; } +/*! \brief + \param +*/ +static inline int eia608_test_second_channel_bit(uint16_t cc_data) { return (cc_data & 0x0800); } + +//////////////////////////////////////////////////////////////////////////////// +// cc_data types +/*! \brief + \param +*/ +static inline int eia608_is_basicna(uint16_t cc_data) { return 0x0000 != (0x6000 & cc_data); /*&& 0x1F00 < (0x7F00 & cc_data);*/ } +/*! \brief + \param +*/ +static inline int eia608_is_preamble(uint16_t cc_data) { return 0x1040 == (0x7040 & cc_data); } +/*! \brief + \param +*/ +static inline int eia608_is_midrowchange(uint16_t cc_data) { return 0x1120 == (0x7770 & cc_data); } +/*! \brief + \param +*/ +static inline int eia608_is_specialna(uint16_t cc_data) { return 0x1130 == (0x7770 & cc_data); } +/*! \brief + \param +*/ +static inline int eia608_is_xds(uint16_t cc_data) { return 0x0000 == (0x7070 & cc_data) && 0x0000 != (0x0F0F & cc_data); } +/*! \brief + \param +*/ +static inline int eia608_is_westeu(uint16_t cc_data) { return 0x1220 == (0x7660 & cc_data); } +/*! \brief + \param +*/ +static inline int eia608_is_control(uint16_t cc_data) { return 0x1420 == (0x7670 & cc_data) || 0x1720 == (0x7770 & cc_data); } +/*! \brief + \param +*/ +static inline int eia608_is_norpak(uint16_t cc_data) { return 0x1724 == (0x777C & cc_data) || 0x1728 == (0x777C & cc_data); } +/*! \brief + \param +*/ +static inline int eia608_is_padding(uint16_t cc_data) { return 0x8080 == cc_data; } + +//////////////////////////////////////////////////////////////////////////////// +// preamble +typedef enum { + eia608_style_white = 0, + eia608_style_green = 1, + eia608_style_blue = 2, + eia608_style_cyan = 3, + eia608_style_red = 4, + eia608_style_yellow = 5, + eia608_style_magenta = 6, + eia608_style_italics = 7, +} eia608_style_t; + +/*! \brief + \param +*/ +int eia608_parse_preamble(uint16_t cc_data, int* row, int* col, eia608_style_t* style, int* chan, int* underline); +/*! \brief + \param +*/ +int eia608_parse_midrowchange(uint16_t cc_data, int* chan, eia608_style_t* style, int* underline); +/*! \brief + \param +*/ +uint16_t eia608_row_column_pramble(int row, int col, int chan, int underline); +/*! \brief + \param +*/ +uint16_t eia608_row_style_pramble(int row, int chan, eia608_style_t style, int underline); +/*! \brief + \param +*/ +uint16_t eia608_midrow_change(int chan, eia608_style_t style, int underline); +//////////////////////////////////////////////////////////////////////////////// +// control command +typedef enum { + eia608_tab_offset_0 = 0x1720, + eia608_tab_offset_1 = 0x1721, + eia608_tab_offset_2 = 0x1722, + eia608_tab_offset_3 = 0x1723, + eia608_control_resume_caption_loading = 0x1420, + eia608_control_backspace = 0x1421, + eia608_control_alarm_off = 0x1422, + eia608_control_alarm_on = 0x1423, + eia608_control_delete_to_end_of_row = 0x1424, + eia608_control_roll_up_2 = 0x1425, + eia608_control_roll_up_3 = 0x1426, + eia608_control_roll_up_4 = 0x1427, + eia608_control_resume_direct_captioning = 0x1429, + eia608_control_text_restart = 0x142A, + eia608_control_text_resume_text_display = 0x142B, + eia608_control_erase_display_memory = 0x142C, + eia608_control_carriage_return = 0x142D, + eia608_control_erase_non_displayed_memory = 0x142E, + eia608_control_end_of_caption = 0x142F, +} eia608_control_t; + +/*! \brief + \param +*/ +uint16_t eia608_control_command(eia608_control_t cmd, int cc); +/*! \brief + \param +*/ +static inline uint16_t eia608_tab(int size, int cc) { return eia608_control_command((eia608_control_t)(eia608_tab_offset_0 | (size & 0x0F)), cc); } +/*! \brief + \param +*/ +eia608_control_t eia608_parse_control(uint16_t cc_data, int* cc); +//////////////////////////////////////////////////////////////////////////////// +// text +/*! \brief + \param c +*/ +uint16_t eia608_from_utf8_1(const utf8_char_t* c, int chan); +/*! \brief + \param +*/ +uint16_t eia608_from_utf8_2(const utf8_char_t* c1, const utf8_char_t* c2); +/*! \brief + \param +*/ +uint16_t eia608_from_basicna(uint16_t bna1, uint16_t bna2); +/*! \brief + \param +*/ +int eia608_to_utf8(uint16_t c, int* chan, utf8_char_t* char1, utf8_char_t* char2); +//////////////////////////////////////////////////////////////////////////////// +/*! \brief + \param +*/ +void eia608_dump(uint16_t cc_data); +/*! \brief + \param +*/ +int eia608_to_text (char *buf, ssize_t size, uint16_t cc_data); +//////////////////////////////////////////////////////////////////////////////// +#ifdef __cplusplus +} +#endif +#endif diff --git a/subprojects/gst-plugins-bad/sys/dwrite/libcaption/eia608_charmap.c b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/eia608_charmap.c new file mode 100644 index 0000000000..705a2737fc --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/eia608_charmap.c @@ -0,0 +1,208 @@ +/**********************************************************************************************/ +/* The MIT License */ +/* */ +/* Copyright 2016-2017 Twitch Interactive, Inc. or its affiliates. All Rights Reserved. */ +/* */ +/* 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 "eia608_charmap.h" +// 0 - 95: Basic North American character set +// 96 - 111: Special North American character +// 112 - 127: Extended Western European character set : Extended Spanish/Miscellaneous +// 128 - 143: Extended Western European character set : Extended French +// 144 - 159: Extended Western European character set : Portuguese +// 160 - 175: Extended Western European character set : German/Danish +const char *eia608_char_map[] = { + EIA608_CHAR_SPACE, + EIA608_CHAR_EXCLAMATION_MARK, + EIA608_CHAR_QUOTATION_MARK, + EIA608_CHAR_NUMBER_SIGN, + EIA608_CHAR_DOLLAR_SIGN, + EIA608_CHAR_PERCENT_SIGN, + EIA608_CHAR_AMPERSAND, + EIA608_CHAR_RIGHT_SINGLE_QUOTATION_MARK, + EIA608_CHAR_LEFT_PARENTHESIS, + EIA608_CHAR_RIGHT_PARENTHESIS, + EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_ACUTE, + EIA608_CHAR_PLUS_SIGN, + EIA608_CHAR_COMMA, + EIA608_CHAR_HYPHEN_MINUS, + EIA608_CHAR_FULL_STOP, + EIA608_CHAR_SOLIDUS, + EIA608_CHAR_DIGIT_ZERO, + EIA608_CHAR_DIGIT_ONE, + EIA608_CHAR_DIGIT_TWO, + EIA608_CHAR_DIGIT_THREE, + EIA608_CHAR_DIGIT_FOUR, + EIA608_CHAR_DIGIT_FIVE, + EIA608_CHAR_DIGIT_SIX, + EIA608_CHAR_DIGIT_SEVEN, + EIA608_CHAR_DIGIT_EIGHT, + EIA608_CHAR_DIGIT_NINE, + EIA608_CHAR_COLON, + EIA608_CHAR_SEMICOLON, + EIA608_CHAR_LESS_THAN_SIGN, + EIA608_CHAR_EQUALS_SIGN, + EIA608_CHAR_GREATER_THAN_SIGN, + EIA608_CHAR_QUESTION_MARK, + EIA608_CHAR_COMMERCIAL_AT, + EIA608_CHAR_LATIN_CAPITAL_LETTER_A, + EIA608_CHAR_LATIN_CAPITAL_LETTER_B, + EIA608_CHAR_LATIN_CAPITAL_LETTER_C, + EIA608_CHAR_LATIN_CAPITAL_LETTER_D, + EIA608_CHAR_LATIN_CAPITAL_LETTER_E, + EIA608_CHAR_LATIN_CAPITAL_LETTER_F, + EIA608_CHAR_LATIN_CAPITAL_LETTER_G, + EIA608_CHAR_LATIN_CAPITAL_LETTER_H, + EIA608_CHAR_LATIN_CAPITAL_LETTER_I, + EIA608_CHAR_LATIN_CAPITAL_LETTER_J, + EIA608_CHAR_LATIN_CAPITAL_LETTER_K, + EIA608_CHAR_LATIN_CAPITAL_LETTER_L, + EIA608_CHAR_LATIN_CAPITAL_LETTER_M, + EIA608_CHAR_LATIN_CAPITAL_LETTER_N, + EIA608_CHAR_LATIN_CAPITAL_LETTER_O, + EIA608_CHAR_LATIN_CAPITAL_LETTER_P, + EIA608_CHAR_LATIN_CAPITAL_LETTER_Q, + EIA608_CHAR_LATIN_CAPITAL_LETTER_R, + EIA608_CHAR_LATIN_CAPITAL_LETTER_S, + EIA608_CHAR_LATIN_CAPITAL_LETTER_T, + EIA608_CHAR_LATIN_CAPITAL_LETTER_U, + EIA608_CHAR_LATIN_CAPITAL_LETTER_V, + EIA608_CHAR_LATIN_CAPITAL_LETTER_W, + EIA608_CHAR_LATIN_CAPITAL_LETTER_X, + EIA608_CHAR_LATIN_CAPITAL_LETTER_Y, + EIA608_CHAR_LATIN_CAPITAL_LETTER_Z, + EIA608_CHAR_LEFT_SQUARE_BRACKET, + EIA608_CHAR_LATIN_SMALL_LETTER_E_WITH_ACUTE, + EIA608_CHAR_RIGHT_SQUARE_BRACKET, + EIA608_CHAR_LATIN_SMALL_LETTER_I_WITH_ACUTE, + EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_ACUTE, + EIA608_CHAR_LATIN_SMALL_LETTER_U_WITH_ACUTE, + EIA608_CHAR_LATIN_SMALL_LETTER_A, + EIA608_CHAR_LATIN_SMALL_LETTER_B, + EIA608_CHAR_LATIN_SMALL_LETTER_C, + EIA608_CHAR_LATIN_SMALL_LETTER_D, + EIA608_CHAR_LATIN_SMALL_LETTER_E, + EIA608_CHAR_LATIN_SMALL_LETTER_F, + EIA608_CHAR_LATIN_SMALL_LETTER_G, + EIA608_CHAR_LATIN_SMALL_LETTER_H, + EIA608_CHAR_LATIN_SMALL_LETTER_I, + EIA608_CHAR_LATIN_SMALL_LETTER_J, + EIA608_CHAR_LATIN_SMALL_LETTER_K, + EIA608_CHAR_LATIN_SMALL_LETTER_L, + EIA608_CHAR_LATIN_SMALL_LETTER_M, + EIA608_CHAR_LATIN_SMALL_LETTER_N, + EIA608_CHAR_LATIN_SMALL_LETTER_O, + EIA608_CHAR_LATIN_SMALL_LETTER_P, + EIA608_CHAR_LATIN_SMALL_LETTER_Q, + EIA608_CHAR_LATIN_SMALL_LETTER_R, + EIA608_CHAR_LATIN_SMALL_LETTER_S, + EIA608_CHAR_LATIN_SMALL_LETTER_T, + EIA608_CHAR_LATIN_SMALL_LETTER_U, + EIA608_CHAR_LATIN_SMALL_LETTER_V, + EIA608_CHAR_LATIN_SMALL_LETTER_W, + EIA608_CHAR_LATIN_SMALL_LETTER_X, + EIA608_CHAR_LATIN_SMALL_LETTER_Y, + EIA608_CHAR_LATIN_SMALL_LETTER_Z, + EIA608_CHAR_LATIN_SMALL_LETTER_C_WITH_CEDILLA, + EIA608_CHAR_DIVISION_SIGN, + EIA608_CHAR_LATIN_CAPITAL_LETTER_N_WITH_TILDE, + EIA608_CHAR_LATIN_SMALL_LETTER_N_WITH_TILDE, + EIA608_CHAR_FULL_BLOCK, + EIA608_CHAR_REGISTERED_SIGN, + EIA608_CHAR_DEGREE_SIGN, + EIA608_CHAR_VULGAR_FRACTION_ONE_HALF, + EIA608_CHAR_INVERTED_QUESTION_MARK, + EIA608_CHAR_TRADE_MARK_SIGN, + EIA608_CHAR_CENT_SIGN, + EIA608_CHAR_POUND_SIGN, + EIA608_CHAR_EIGHTH_NOTE, + EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_GRAVE, + EIA608_CHAR_NO_BREAK_SPACE, + EIA608_CHAR_LATIN_SMALL_LETTER_E_WITH_GRAVE, + EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX, + EIA608_CHAR_LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX, + EIA608_CHAR_LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX, + EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX, + EIA608_CHAR_LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX, + EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_ACUTE, + EIA608_CHAR_LATIN_CAPITAL_LETTER_E_WITH_ACUTE, + EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_ACUTE, + EIA608_CHAR_LATIN_CAPITAL_LETTER_U_WITH_ACUTE, + EIA608_CHAR_LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS, + EIA608_CHAR_LATIN_SMALL_LETTER_U_WITH_DIAERESIS, + EIA608_CHAR_LEFT_SINGLE_QUOTATION_MARK, + EIA608_CHAR_INVERTED_EXCLAMATION_MARK, + EIA608_CHAR_ASTERISK, + EIA608_CHAR_APOSTROPHE, + EIA608_CHAR_EM_DASH, + EIA608_CHAR_COPYRIGHT_SIGN, + EIA608_CHAR_SERVICE_MARK, + EIA608_CHAR_BULLET, + EIA608_CHAR_LEFT_DOUBLE_QUOTATION_MARK, + EIA608_CHAR_RIGHT_DOUBLE_QUOTATION_MARK, + EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_GRAVE, + EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_CIRCUMFLEX, + EIA608_CHAR_LATIN_CAPITAL_LETTER_C_WITH_CEDILLA, + EIA608_CHAR_LATIN_CAPITAL_LETTER_E_WITH_GRAVE, + EIA608_CHAR_LATIN_CAPITAL_LETTER_E_WITH_CIRCUMFLEX, + EIA608_CHAR_LATIN_CAPITAL_LETTER_E_WITH_DIAERESIS, + EIA608_CHAR_LATIN_SMALL_LETTER_E_WITH_DIAERESIS, + EIA608_CHAR_LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX, + EIA608_CHAR_LATIN_CAPITAL_LETTER_I_WITH_DIAERESIS, + EIA608_CHAR_LATIN_SMALL_LETTER_I_WITH_DIAERESIS, + EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_CIRCUMFLEX, + EIA608_CHAR_LATIN_CAPITAL_LETTER_U_WITH_GRAVE, + EIA608_CHAR_LATIN_SMALL_LETTER_U_WITH_GRAVE, + EIA608_CHAR_LATIN_CAPITAL_LETTER_U_WITH_CIRCUMFLEX, + EIA608_CHAR_LEFT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK, + EIA608_CHAR_RIGHT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK, + EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_TILDE, + EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_TILDE, + EIA608_CHAR_LATIN_CAPITAL_LETTER_I_WITH_ACUTE, + EIA608_CHAR_LATIN_CAPITAL_LETTER_I_WITH_GRAVE, + EIA608_CHAR_LATIN_SMALL_LETTER_I_WITH_GRAVE, + EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_GRAVE, + EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_GRAVE, + EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_TILDE, + EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_TILDE, + EIA608_CHAR_LEFT_CURLY_BRACKET, + EIA608_CHAR_RIGHT_CURLY_BRACKET, + EIA608_CHAR_REVERSE_SOLIDUS, + EIA608_CHAR_CIRCUMFLEX_ACCENT, + EIA608_CHAR_LOW_LINE, + EIA608_CHAR_VERTICAL_LINE, + EIA608_CHAR_TILDE, + EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS, + EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_DIAERESIS, + EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS, + EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_DIAERESIS, + EIA608_CHAR_LATIN_SMALL_LETTER_SHARP_S, + EIA608_CHAR_YEN_SIGN, + EIA608_CHAR_CURRENCY_SIGN, + EIA608_CHAR_BROKEN_BAR, + EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE, + EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_RING_ABOVE, + EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_STROKE, + EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_STROKE, + EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_RIGHT, + EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_LEFT, + EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_RIGHT, + EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_LEFT, +}; diff --git a/subprojects/gst-plugins-bad/sys/dwrite/libcaption/eia608_charmap.h b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/eia608_charmap.h new file mode 100644 index 0000000000..37d334606d --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/eia608_charmap.h @@ -0,0 +1,236 @@ +/**********************************************************************************************/ +/* The MIT License */ +/* */ +/* Copyright 2016-2017 Twitch Interactive, Inc. or its affiliates. All Rights Reserved. */ +/* */ +/* 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. */ +/**********************************************************************************************/ +#ifndef LIBCAPTION_EIA608_CHARMAP_H +#define LIBCAPTION_EIA608_CHARMAP_H +#ifdef __cplusplus +extern "C" { +#endif + +#define EIA608_CHAR_COUNT 176 +extern const char* eia608_char_map[EIA608_CHAR_COUNT]; + +// Helper char +#define EIA608_CHAR_NULL "" +// Basic North American character set +#define EIA608_CHAR_SPACE "\x20" +#define EIA608_CHAR_EXCLAMATION_MARK "\x21" +#define EIA608_CHAR_QUOTATION_MARK "\x22" +#define EIA608_CHAR_NUMBER_SIGN "\x23" +#define EIA608_CHAR_DOLLAR_SIGN "\x24" +#define EIA608_CHAR_PERCENT_SIGN "\x25" +#define EIA608_CHAR_AMPERSAND "\x26" +#define EIA608_CHAR_LEFT_SINGLE_QUOTATION_MARK "\xE2\x80\x98" +#define EIA608_CHAR_LEFT_PARENTHESIS "\x28" +#define EIA608_CHAR_RIGHT_PARENTHESIS "\x29" +#define EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_ACUTE "\xC3\xA1" +#define EIA608_CHAR_PLUS_SIGN "\x2B" +#define EIA608_CHAR_COMMA "\x2C" +#define EIA608_CHAR_HYPHEN_MINUS "\x2D" +#define EIA608_CHAR_FULL_STOP "\x2E" +#define EIA608_CHAR_SOLIDUS "\x2F" + +// Basic North American character set +#define EIA608_CHAR_DIGIT_ZERO "\x30" +#define EIA608_CHAR_DIGIT_ONE "\x31" +#define EIA608_CHAR_DIGIT_TWO "\x32" +#define EIA608_CHAR_DIGIT_THREE "\x33" +#define EIA608_CHAR_DIGIT_FOUR "\x34" +#define EIA608_CHAR_DIGIT_FIVE "\x35" +#define EIA608_CHAR_DIGIT_SIX "\x36" +#define EIA608_CHAR_DIGIT_SEVEN "\x37" +#define EIA608_CHAR_DIGIT_EIGHT "\x38" +#define EIA608_CHAR_DIGIT_NINE "\x39" +#define EIA608_CHAR_COLON "\x3A" +#define EIA608_CHAR_SEMICOLON "\x3B" +#define EIA608_CHAR_LESS_THAN_SIGN "\x3C" +#define EIA608_CHAR_EQUALS_SIGN "\x3D" +#define EIA608_CHAR_GREATER_THAN_SIGN "\x3E" +#define EIA608_CHAR_QUESTION_MARK "\x3F" + +// Basic North American character set +#define EIA608_CHAR_COMMERCIAL_AT "\x40" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_A "\x41" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_B "\x42" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_C "\x43" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_D "\x44" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_E "\x45" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_F "\x46" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_G "\x47" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_H "\x48" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_I "\x49" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_J "\x4A" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_K "\x4B" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_L "\x4C" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_M "\x4D" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_N "\x4E" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_O "\x4F" + +// Basic North American character set +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_P "\x50" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_Q "\x51" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_R "\x52" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_S "\x53" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_T "\x54" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_U "\x55" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_V "\x56" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_W "\x57" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_X "\x58" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_Y "\x59" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_Z "\x5A" +#define EIA608_CHAR_LEFT_SQUARE_BRACKET "\x5B" +#define EIA608_CHAR_LATIN_SMALL_LETTER_E_WITH_ACUTE "\xC3\xA9" +#define EIA608_CHAR_RIGHT_SQUARE_BRACKET "\x5D" +#define EIA608_CHAR_LATIN_SMALL_LETTER_I_WITH_ACUTE "\xC3\xAD" +#define EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_ACUTE "\xC3\xB3" + +// Basic North American character set +#define EIA608_CHAR_LATIN_SMALL_LETTER_U_WITH_ACUTE "\xC3\xBA" +#define EIA608_CHAR_LATIN_SMALL_LETTER_A "\x61" +#define EIA608_CHAR_LATIN_SMALL_LETTER_B "\x62" +#define EIA608_CHAR_LATIN_SMALL_LETTER_C "\x63" +#define EIA608_CHAR_LATIN_SMALL_LETTER_D "\x64" +#define EIA608_CHAR_LATIN_SMALL_LETTER_E "\x65" +#define EIA608_CHAR_LATIN_SMALL_LETTER_F "\x66" +#define EIA608_CHAR_LATIN_SMALL_LETTER_G "\x67" +#define EIA608_CHAR_LATIN_SMALL_LETTER_H "\x68" +#define EIA608_CHAR_LATIN_SMALL_LETTER_I "\x69" +#define EIA608_CHAR_LATIN_SMALL_LETTER_J "\x6A" +#define EIA608_CHAR_LATIN_SMALL_LETTER_K "\x6B" +#define EIA608_CHAR_LATIN_SMALL_LETTER_L "\x6C" +#define EIA608_CHAR_LATIN_SMALL_LETTER_M "\x6D" +#define EIA608_CHAR_LATIN_SMALL_LETTER_N "\x6E" +#define EIA608_CHAR_LATIN_SMALL_LETTER_O "\x6F" + +// Basic North American character set +#define EIA608_CHAR_LATIN_SMALL_LETTER_P "\x70" +#define EIA608_CHAR_LATIN_SMALL_LETTER_Q "\x71" +#define EIA608_CHAR_LATIN_SMALL_LETTER_R "\x72" +#define EIA608_CHAR_LATIN_SMALL_LETTER_S "\x73" +#define EIA608_CHAR_LATIN_SMALL_LETTER_T "\x74" +#define EIA608_CHAR_LATIN_SMALL_LETTER_U "\x75" +#define EIA608_CHAR_LATIN_SMALL_LETTER_V "\x76" +#define EIA608_CHAR_LATIN_SMALL_LETTER_W "\x77" +#define EIA608_CHAR_LATIN_SMALL_LETTER_X "\x78" +#define EIA608_CHAR_LATIN_SMALL_LETTER_Y "\x79" +#define EIA608_CHAR_LATIN_SMALL_LETTER_Z "\x7A" +#define EIA608_CHAR_LATIN_SMALL_LETTER_C_WITH_CEDILLA "\xC3\xA7" +#define EIA608_CHAR_DIVISION_SIGN "\xC3\xB7" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_N_WITH_TILDE "\xC3\x91" +#define EIA608_CHAR_LATIN_SMALL_LETTER_N_WITH_TILDE "\xC3\xB1" +#define EIA608_CHAR_FULL_BLOCK "\xE2\x96\x88" + +// Special North American character set[edit] +#define EIA608_CHAR_REGISTERED_SIGN "\xC2\xAE" +#define EIA608_CHAR_DEGREE_SIGN "\xC2\xB0" +#define EIA608_CHAR_VULGAR_FRACTION_ONE_HALF "\xC2\xBD" +#define EIA608_CHAR_INVERTED_QUESTION_MARK "\xC2\xBF" +#define EIA608_CHAR_TRADE_MARK_SIGN "\xE2\x84\xA2" +#define EIA608_CHAR_CENT_SIGN "\xC2\xA2" +#define EIA608_CHAR_POUND_SIGN "\xC2\xA3" +#define EIA608_CHAR_EIGHTH_NOTE "\xE2\x99\xAA" +#define EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_GRAVE "\xC3\xA0" +#define EIA608_CHAR_NO_BREAK_SPACE "\xC2\xA0" +#define EIA608_CHAR_LATIN_SMALL_LETTER_E_WITH_GRAVE "\xC3\xA8" +#define EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX "\xC3\xA2" +#define EIA608_CHAR_LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX "\xC3\xAA" +#define EIA608_CHAR_LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX "\xC3\xAE" +#define EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX "\xC3\xB4" +#define EIA608_CHAR_LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX "\xC3\xBB" + +// Extended Western European character set : Extended Spanish/Miscellaneous +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_ACUTE "\xC3\x81" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_E_WITH_ACUTE "\xC3\x89" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_ACUTE "\xC3\x93" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_U_WITH_ACUTE "\xC3\x9A" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS "\xC3\x9C" +#define EIA608_CHAR_LATIN_SMALL_LETTER_U_WITH_DIAERESIS "\xC3\xBC" +#define EIA608_CHAR_RIGHT_SINGLE_QUOTATION_MARK "\xE2\x80\x99" +#define EIA608_CHAR_INVERTED_EXCLAMATION_MARK "\xC2\xA1" +#define EIA608_CHAR_ASTERISK "\x2A" +#define EIA608_CHAR_APOSTROPHE "\x27" +#define EIA608_CHAR_EM_DASH "\xE2\x80\x94" +#define EIA608_CHAR_COPYRIGHT_SIGN "\xC2\xA9" +#define EIA608_CHAR_SERVICE_MARK "\xE2\x84\xA0" +#define EIA608_CHAR_BULLET "\xE2\x80\xA2" +#define EIA608_CHAR_LEFT_DOUBLE_QUOTATION_MARK "\xE2\x80\x9C" +#define EIA608_CHAR_RIGHT_DOUBLE_QUOTATION_MARK "\xE2\x80\x9D" + +// Extended Western European character set : Extended French +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_GRAVE "\xC3\x80" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_CIRCUMFLEX "\xC3\x82" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_C_WITH_CEDILLA "\xC3\x87" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_E_WITH_GRAVE "\xC3\x88" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_E_WITH_CIRCUMFLEX "\xC3\x8A" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_E_WITH_DIAERESIS "\xC3\x8B" +#define EIA608_CHAR_LATIN_SMALL_LETTER_E_WITH_DIAERESIS "\xC3\xAB" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX "\xC3\x8E" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_I_WITH_DIAERESIS "\xC3\x8F" +#define EIA608_CHAR_LATIN_SMALL_LETTER_I_WITH_DIAERESIS "\xC3\xAF" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_CIRCUMFLEX "\xC3\x94" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_U_WITH_GRAVE "\xC3\x99" +#define EIA608_CHAR_LATIN_SMALL_LETTER_U_WITH_GRAVE "\xC3\xB9" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_U_WITH_CIRCUMFLEX "\xC3\x9B" +#define EIA608_CHAR_LEFT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK "\xC2\xAB" +#define EIA608_CHAR_RIGHT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK "\xC2\xBB" + +// Extended Western European character set : Portuguese +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_TILDE "\xC3\x83" +#define EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_TILDE "\xC3\xA3" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_I_WITH_ACUTE "\xC3\x8D" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_I_WITH_GRAVE "\xC3\x8C" +#define EIA608_CHAR_LATIN_SMALL_LETTER_I_WITH_GRAVE "\xC3\xAC" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_GRAVE "\xC3\x92" +#define EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_GRAVE "\xC3\xB2" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_TILDE "\xC3\x95" +#define EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_TILDE "\xC3\xB5" +#define EIA608_CHAR_LEFT_CURLY_BRACKET "\x7B" +#define EIA608_CHAR_RIGHT_CURLY_BRACKET "\x7D" +#define EIA608_CHAR_REVERSE_SOLIDUS "\x5C" +#define EIA608_CHAR_CIRCUMFLEX_ACCENT "\x5E" +#define EIA608_CHAR_LOW_LINE "\x5F" +#define EIA608_CHAR_VERTICAL_LINE "\x7C" +#define EIA608_CHAR_TILDE "\x7E" + +// Extended Western European character set : German/Danish +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS "\xC3\x84" +#define EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_DIAERESIS "\xC3\xA4" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS "\xC3\x96" +#define EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_DIAERESIS "\xC3\xB6" +#define EIA608_CHAR_LATIN_SMALL_LETTER_SHARP_S "\xC3\x9F" +#define EIA608_CHAR_YEN_SIGN "\xC2\xA5" +#define EIA608_CHAR_CURRENCY_SIGN "\xC2\xA4" +#define EIA608_CHAR_BROKEN_BAR "\xC2\xA6" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE "\xC3\x85" +#define EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_RING_ABOVE "\xC3\xA5" +#define EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_STROKE "\xC3\x98" +#define EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_STROKE "\xC3\xB8" +#define EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_RIGHT "\xE2\x94\x8C" // top left +#define EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_LEFT "\xE2\x94\x90" // top right +#define EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_RIGHT "\xE2\x94\x94" // lower left +#define EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_LEFT "\xE2\x94\x98" // bottom right + +#ifdef __cplusplus +} +#endif +#endif diff --git a/subprojects/gst-plugins-bad/sys/dwrite/libcaption/eia608_from_utf8.c b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/eia608_from_utf8.c new file mode 100644 index 0000000000..cd7412b990 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/eia608_from_utf8.c @@ -0,0 +1,799 @@ +/* Generated by re2c 1.0.3 on Tue Jun 19 17:18:11 2018 */ +/**********************************************************************************************/ +/* The MIT License */ +/* */ +/* Copyright 2016-2017 Twitch Interactive, Inc. or its affiliates. All Rights Reserved. */ +/* */ +/* 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 "utf8.h" +#include +#include + +uint16_t +_eia608_from_utf8 (const utf8_char_t * s) +{ + const unsigned char *YYMARKER = 0; + const unsigned char *YYCURSOR = (const unsigned char *) s; + + if (0 == s) { + return 0x0000; + } + + + { + unsigned char yych; + yych = *YYCURSOR; + if (yych <= '`') { + if (yych <= '*') { + if (yych <= '&') { + if (yych <= 0x00) + goto yy2; + if (yych <= 0x1F) + goto yy4; + goto yy6; + } else { + if (yych <= '\'') + goto yy8; + if (yych <= ')') + goto yy6; + goto yy10; + } + } else { + if (yych <= ']') { + if (yych == '\\') + goto yy12; + goto yy6; + } else { + if (yych <= '^') + goto yy14; + if (yych <= '_') + goto yy16; + goto yy18; + } + } + } else { + if (yych <= 0x7F) { + if (yych <= '|') { + if (yych <= 'z') + goto yy6; + if (yych <= '{') + goto yy20; + goto yy22; + } else { + if (yych <= '}') + goto yy24; + if (yych <= '~') + goto yy26; + goto yy28; + } + } else { + if (yych <= 0xC3) { + if (yych <= 0xC1) + goto yy4; + if (yych <= 0xC2) + goto yy30; + goto yy31; + } else { + if (yych == 0xE2) + goto yy32; + goto yy4; + } + } + } + yy2: + ++YYCURSOR; + { + /*NULL*/ return 0x0000; + } + yy4: + ++YYCURSOR; + yy5: + { /*DEFAULT_RULE */ + return 0x0000; + } + yy6: + ++YYCURSOR; + { /*ASCII range */ + return (s[0] << 8) & 0xFF00; + } + yy8: + ++YYCURSOR; + { /*APOSTROPHE -> RIGHT_SINGLE_QUOTATION_MARK */ + return 0x1229; + } + yy10: + ++YYCURSOR; + { + /*ASTERISK*/ return 0x1228; + } + yy12: + ++YYCURSOR; + { /*REVERSE_SOLIDUS */ + return 0x132B; + } + yy14: + ++YYCURSOR; + { /*CIRCUMFLEX_ACCENT */ + return 0x132C; + } + yy16: + ++YYCURSOR; + { /*LOW_LINE */ + return 0x132D; + } + yy18: + ++YYCURSOR; + { /*GRAVE_ACCENT -> LEFT_SINGLE_QUOTATION_MARK */ + return 0x1226; + } + yy20: + ++YYCURSOR; + { /*LEFT_CURLY_BRACKET */ + return 0x1329; + } + yy22: + ++YYCURSOR; + { /*VERTICAL_LINE */ + return 0x132E; + } + yy24: + ++YYCURSOR; + { /*RIGHT_CURLY_BRACKET */ + return 0x132A; + } + yy26: + ++YYCURSOR; + { + /*TILDE*/ return 0x132F; + } + yy28: + ++YYCURSOR; + { /*DEL/BACKSPACE. Need to set bits 9 and 12! return 0x1421; */ + return 0x0000; + } + yy30: + yych = *++YYCURSOR; + switch (yych) { + case 0xA0: + goto yy33; + case 0xA1: + goto yy35; + case 0xA2: + goto yy37; + case 0xA3: + goto yy39; + case 0xA4: + goto yy41; + case 0xA5: + goto yy43; + case 0xA6: + goto yy45; + case 0xA9: + goto yy47; + case 0xAB: + goto yy49; + case 0xAE: + goto yy51; + case 0xB0: + goto yy53; + case 0xBB: + goto yy55; + case 0xBD: + goto yy57; + case 0xBF: + goto yy59; + default: + goto yy5; + } + yy31: + yych = *++YYCURSOR; + switch (yych) { + case 0x80: + goto yy61; + case 0x81: + goto yy63; + case 0x82: + goto yy65; + case 0x83: + goto yy67; + case 0x84: + goto yy69; + case 0x85: + goto yy71; + case 0x87: + goto yy73; + case 0x88: + goto yy75; + case 0x89: + goto yy77; + case 0x8A: + goto yy79; + case 0x8B: + goto yy81; + case 0x8C: + goto yy83; + case 0x8D: + goto yy85; + case 0x8E: + goto yy87; + case 0x8F: + goto yy89; + case 0x91: + goto yy91; + case 0x92: + goto yy93; + case 0x93: + goto yy95; + case 0x94: + goto yy97; + case 0x95: + goto yy99; + case 0x96: + goto yy101; + case 0x98: + goto yy103; + case 0x99: + goto yy105; + case 0x9A: + goto yy107; + case 0x9B: + goto yy109; + case 0x9C: + goto yy111; + case 0x9F: + goto yy113; + case 0xA0: + goto yy115; + case 0xA1: + goto yy117; + case 0xA2: + goto yy119; + case 0xA3: + goto yy121; + case 0xA4: + goto yy123; + case 0xA5: + goto yy125; + case 0xA7: + goto yy127; + case 0xA8: + goto yy129; + case 0xA9: + goto yy131; + case 0xAA: + goto yy133; + case 0xAB: + goto yy135; + case 0xAC: + goto yy137; + case 0xAD: + goto yy139; + case 0xAE: + goto yy141; + case 0xAF: + goto yy143; + case 0xB1: + goto yy145; + case 0xB2: + goto yy147; + case 0xB3: + goto yy149; + case 0xB4: + goto yy151; + case 0xB5: + goto yy153; + case 0xB6: + goto yy155; + case 0xB7: + goto yy157; + case 0xB8: + goto yy159; + case 0xB9: + goto yy161; + case 0xBA: + goto yy163; + case 0xBB: + goto yy165; + case 0xBC: + goto yy167; + default: + goto yy5; + } + yy32: + yych = *(YYMARKER = ++YYCURSOR); + switch (yych) { + case 0x80: + goto yy169; + case 0x84: + goto yy171; + case 0x94: + goto yy172; + case 0x96: + goto yy173; + case 0x99: + goto yy174; + default: + goto yy5; + } + yy33: + ++YYCURSOR; + { /*NO_BREAK_SPACE */ + return 0x1139; + } + yy35: + ++YYCURSOR; + { /*INVERTED_EXCLAMATION_MARK */ + return 0x1227; + } + yy37: + ++YYCURSOR; + { /*CENT_SIGN */ + return 0x1135; + } + yy39: + ++YYCURSOR; + { /*POUND_SIGN */ + return 0x1136; + } + yy41: + ++YYCURSOR; + { /*CURRENCY_SIGN */ + return 0x1336; + } + yy43: + ++YYCURSOR; + { /*YEN_SIGN */ + return 0x1335; + } + yy45: + ++YYCURSOR; + { /*BROKEN_BAR */ + return 0x1337; + } + yy47: + ++YYCURSOR; + { /*COPYRIGHT_SIGN */ + return 0x122B; + } + yy49: + ++YYCURSOR; + { /*LEFT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK */ + return 0x123E; + } + yy51: + ++YYCURSOR; + { /*REGISTERED_SIGN */ + return 0x1130; + } + yy53: + ++YYCURSOR; + { /*DEGREE_SIGN */ + return 0x1131; + } + yy55: + ++YYCURSOR; + { /*RIGHT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK */ + return 0x123F; + } + yy57: + ++YYCURSOR; + { /*VULGAR_FRACTION_ONE_HALF */ + return 0x1132; + } + yy59: + ++YYCURSOR; + { /*INVERTED_QUESTION_MARK */ + return 0x1133; + } + yy61: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_A_WITH_GRAVE */ + return 0x1230; + } + yy63: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_A_WITH_ACUTE */ + return 0x1220; + } + yy65: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_A_WITH_CIRCUMFLEX */ + return 0x1231; + } + yy67: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_A_WITH_TILDE */ + return 0x1320; + } + yy69: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS */ + return 0x1330; + } + yy71: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE */ + return 0x1338; + } + yy73: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_C_WITH_CEDILLA */ + return 0x1232; + } + yy75: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_E_WITH_GRAVE */ + return 0x1233; + } + yy77: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_E_WITH_ACUTE */ + return 0x1221; + } + yy79: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_E_WITH_CIRCUMFLEX */ + return 0x1234; + } + yy81: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_E_WITH_DIAERESIS */ + return 0x1235; + } + yy83: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_I_WITH_GRAVE */ + return 0x1323; + } + yy85: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_I_WITH_ACUTE */ + return 0x1322; + } + yy87: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX */ + return 0x1237; + } + yy89: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_I_WITH_DIAERESIS */ + return 0x1238; + } + yy91: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_N_WITH_TILDE */ + return 0x7D00; + } + yy93: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_O_WITH_GRAVE */ + return 0x1325; + } + yy95: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_O_WITH_ACUTE */ + return 0x1222; + } + yy97: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_O_WITH_CIRCUMFLEX */ + return 0x123A; + } + yy99: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_O_WITH_TILDE */ + return 0x1327; + } + yy101: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS */ + return 0x1332; + } + yy103: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_O_WITH_STROKE */ + return 0x133A; + } + yy105: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_U_WITH_GRAVE */ + return 0x123B; + } + yy107: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_U_WITH_ACUTE */ + return 0x1223; + } + yy109: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_U_WITH_CIRCUMFLEX */ + return 0x123D; + } + yy111: + ++YYCURSOR; + { /*LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS */ + return 0x1224; + } + yy113: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_SHARP_S */ + return 0x1334; + } + yy115: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_A_WITH_GRAVE */ + return 0x1138; + } + yy117: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_A_WITH_ACUTE */ + return 0x2A00; + } + yy119: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX */ + return 0x113B; + } + yy121: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_A_WITH_TILDE */ + return 0x1321; + } + yy123: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_A_WITH_DIAERESIS */ + return 0x1331; + } + yy125: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_A_WITH_RING_ABOVE */ + return 0x1339; + } + yy127: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_C_WITH_CEDILLA */ + return 0x7B00; + } + yy129: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_E_WITH_GRAVE */ + return 0x113A; + } + yy131: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_E_WITH_ACUTE */ + return 0x5C00; + } + yy133: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX */ + return 0x113C; + } + yy135: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_E_WITH_DIAERESIS */ + return 0x1236; + } + yy137: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_I_WITH_GRAVE */ + return 0x1324; + } + yy139: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_I_WITH_ACUTE */ + return 0x5E00; + } + yy141: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX */ + return 0x113D; + } + yy143: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_I_WITH_DIAERESIS */ + return 0x1239; + } + yy145: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_N_WITH_TILDE */ + return 0x7E00; + } + yy147: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_O_WITH_GRAVE */ + return 0x1326; + } + yy149: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_O_WITH_ACUTE */ + return 0x5F00; + } + yy151: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX */ + return 0x113E; + } + yy153: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_O_WITH_TILDE */ + return 0x1328; + } + yy155: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_O_WITH_DIAERESIS */ + return 0x1333; + } + yy157: + ++YYCURSOR; + { /*DIVISION_SIGN */ + return 0x7C00; + } + yy159: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_O_WITH_STROKE */ + return 0x133B; + } + yy161: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_U_WITH_GRAVE */ + return 0x123C; + } + yy163: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_U_WITH_ACUTE */ + return 0x6000; + } + yy165: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX */ + return 0x113F; + } + yy167: + ++YYCURSOR; + { /*LATIN_SMALL_LETTER_U_WITH_DIAERESIS */ + return 0x1225; + } + yy169: + yych = *++YYCURSOR; + switch (yych) { + case 0x94: + goto yy175; + case 0x98: + goto yy177; + case 0x99: + goto yy179; + case 0x9C: + goto yy181; + case 0x9D: + goto yy183; + case 0xA2: + goto yy185; + default: + goto yy170; + } + yy170: + YYCURSOR = YYMARKER; + goto yy5; + yy171: + yych = *++YYCURSOR; + if (yych == 0xA0) + goto yy187; + if (yych == 0xA2) + goto yy189; + goto yy170; + yy172: + yych = *++YYCURSOR; + switch (yych) { + case 0x8C: + goto yy191; + case 0x90: + goto yy193; + case 0x94: + goto yy195; + case 0x98: + goto yy197; + default: + goto yy170; + } + yy173: + yych = *++YYCURSOR; + if (yych == 0x88) + goto yy199; + goto yy170; + yy174: + yych = *++YYCURSOR; + if (yych == 0xAA) + goto yy201; + goto yy170; + yy175: + ++YYCURSOR; + { /*EM_DASH */ + return 0x122A; + } + yy177: + ++YYCURSOR; + { /*LEFT_SINGLE_QUOTATION_MARK */ + return 0x1226; + } + yy179: + ++YYCURSOR; + { /*RIGHT_SINGLE_QUOTATION_MARK -> APOSTROPHE */ + return 0x2700; + } + yy181: + ++YYCURSOR; + { /*LEFT_DOUBLE_QUOTATION_MARK */ + return 0x122E; + } + yy183: + ++YYCURSOR; + { /*RIGHT_DOUBLE_QUOTATION_MARK */ + return 0x122F; + } + yy185: + ++YYCURSOR; + { + /*BULLET*/ return 0x122D; + } + yy187: + ++YYCURSOR; + { /*SERVICE_MARK */ + return 0x122C; + } + yy189: + ++YYCURSOR; + { /*TRADE_MARK_SIGN */ + return 0x1134; + } + yy191: + ++YYCURSOR; + { /*EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_RIGHT */ + return 0x133C; + } + yy193: + ++YYCURSOR; + { /*EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_LEFT */ + return 0x133D; + } + yy195: + ++YYCURSOR; + { /*EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_RIGHT */ + return 0x133E; + } + yy197: + ++YYCURSOR; + { /*EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_LEFT */ + return 0x133F; + } + yy199: + ++YYCURSOR; + { /*FULL_BLOCK */ + return 0x7F00; + } + yy201: + ++YYCURSOR; + { /*EIGHTH_NOTE */ + return 0x1137; + } + } + +} diff --git a/subprojects/gst-plugins-bad/sys/dwrite/libcaption/utf8.c b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/utf8.c new file mode 100644 index 0000000000..d90c24f16f --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/utf8.c @@ -0,0 +1,261 @@ +/**********************************************************************************************/ +/* The MIT License */ +/* */ +/* Copyright 2016-2017 Twitch Interactive, Inc. or its affiliates. All Rights Reserved. */ +/* */ +/* 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 "utf8.h" +#include +#include +#include + +const utf8_char_t * +utf8_char_next (const utf8_char_t * c) +{ + const utf8_char_t *n = c + utf8_char_length (c); + return n == c ? 0 : n; +} + +// returnes the length of the char in bytes +size_t +utf8_char_length (const utf8_char_t * c) +{ + // count null term as zero size + if (!c || 0x00 == c[0]) { + return 0; + } + + static const size_t _utf8_char_length[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 2, 2, 2, 3, 3, 4, 0 + }; + + return _utf8_char_length[(c[0] >> 3) & 0x1F]; +} + +int +utf8_char_whitespace (const utf8_char_t * c) +{ + // 0x7F is DEL + if (!c || (c[0] >= 0 && c[0] <= ' ') || c[0] == 0x7F) { + return 1; + } + // EIA608_CHAR_NO_BREAK_SPACE TODO other utf8 spaces + if (0xC2 == (unsigned char) c[0] && 0xA0 == (unsigned char) c[1]) { + return 1; + } + + return 0; +} + +// returns length of the string in bytes +// size is number of charcter to count (0 to count until NULL term) +size_t +utf8_string_length (const utf8_char_t * data, utf8_size_t size) +{ + size_t char_length, byts = 0; + + if (0 == size) { + size = utf8_char_count (data, 0); + } + + for (; 0 < size; --size) { + if (0 == (char_length = utf8_char_length (data))) { + break; + } + + data += char_length; + byts += char_length; + } + + return byts; +} + +size_t +utf8_char_copy (utf8_char_t * dst, const utf8_char_t * src) +{ + size_t bytes = utf8_char_length (src); + + if (bytes && dst) { + memcpy (dst, src, bytes); + dst[bytes] = '\0'; + } + + return bytes; +} + +// returnes the number of utf8 charcters in a string given the number of bytes +// to count until the a null terminator, pass 0 for size +utf8_size_t +utf8_char_count (const char *data, size_t size) +{ + size_t i, bytes = 0; + utf8_size_t count = 0; + + if (0 == size) { + size = strlen (data); + } + + for (i = 0; i < size; ++count, i += bytes) { + if (0 == (bytes = utf8_char_length (&data[i]))) { + break; + } + } + + return count; +} + +// returns the length of the line in bytes triming not printable charcters at the end +size_t +utf8_trimmed_length (const utf8_char_t * data, utf8_size_t charcters) +{ + size_t l, t = 0, split_at = 0; + for (size_t c = 0; (*data) && c < charcters; ++c) { + l = utf8_char_length (data); + if (!utf8_char_whitespace (data)) { + split_at = t + l; + } + t += l, data += l; + } + + return split_at; +} + +size_t +_utf8_newline (const utf8_char_t * data) +{ + if ('\r' == data[0]) { + return '\n' == data[1] ? 2 : 1; // windows/unix + } else if ('\n' == data[0]) { + return '\r' == data[1] ? 2 : 1; // riscos/macos + } else { + return 0; + } +} + +// returns the length in bytes of the line including the new line charcter(s) +// auto detects between windows(CRLF), unix(LF), mac(CR) and riscos (LFCR) line endings +size_t +utf8_line_length (const utf8_char_t * data) +{ + size_t n, len = 0; + + for (len = 0; 0 != data[len]; ++len) { + if (0 < (n = _utf8_newline (data))) { + return len + n; + } + + data += utf8_char_length (data); + } + + return len; +} + +// returns number of chars to include before split +utf8_size_t +utf8_wrap_length (const utf8_char_t * data, utf8_size_t size) +{ + // Set split_at to size, so if a split point cna not be found, retuns the size passed in + size_t char_length, char_count, split_at = size; + + for (char_count = 0; char_count <= size; ++char_count) { + if (_utf8_newline (data)) { + return char_count; + } else if (utf8_char_whitespace (data)) { + split_at = char_count; + } + + char_length = utf8_char_length (data); + data += char_length; + } + + return split_at; +} + +int +utf8_line_count (const utf8_char_t * data) +{ + size_t len = 0; + int count = 0; + + do { + len = utf8_line_length (data); + data += len; + ++count; + } while (0 < len); + + return count - 1; +} + +utf8_char_t * +utf8_load_text_file (const char *path, size_t * size) +{ + utf8_char_t *data = NULL; + FILE *file = fopen (path, "r"); + + if (file) { + fseek (file, 0, SEEK_END); + size_t file_size = ftell (file); + fseek (file, 0, SEEK_SET); + + if (0 == (*size) || file_size <= (*size)) { + (*size) = 0; + data = (utf8_char_t *) malloc (1 + file_size); + memset (data, '\0', file_size); + + if (data) { + utf8_char_t *pos = data; + size_t bytes_read = 0; + + while (0 < (bytes_read = fread (pos, 1, file_size - (*size), file))) { + pos += bytes_read; + (*size) += bytes_read; + } + } + + fclose (file); + } + } + + data[*size] = 0; + return data; +} + +#ifndef strnstr +char * +strnstr (const char *string1, const char *string2, size_t len) +{ + size_t length2; + + length2 = strlen (string2); + if (!length2) { + return (char *) string1; + } + + while (len >= length2) { + len--; + if (!memcmp (string1, string2, length2)) + return (char *) string1; + string1++; + } + return NULL; +} +#endif diff --git a/subprojects/gst-plugins-bad/sys/dwrite/libcaption/utf8.h b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/utf8.h new file mode 100644 index 0000000000..3a17d75abd --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/utf8.h @@ -0,0 +1,128 @@ +/**********************************************************************************************/ +/* The MIT License */ +/* */ +/* Copyright 2016-2017 Twitch Interactive, Inc. or its affiliates. All Rights Reserved. */ +/* */ +/* 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. */ +/**********************************************************************************************/ +#ifndef LIBCAPTION_UTF8_H +#define LIBCAPTION_UTF8_H +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +// These types exist to make the code more self dcoumenting +// utf8_char_t point is a null teminate string of utf8 encodecd chars +// +// utf8_size_t is the length of a string in chars +// size_t is bytes +typedef char utf8_char_t; +typedef size_t utf8_size_t; +/*! \brief + \param + + Skiped continuation bytes +*/ + +const utf8_char_t* utf8_char_next(const utf8_char_t* c); +/*! \brief + \param + + returnes the length of the char in bytes +*/ +size_t utf8_char_length(const utf8_char_t* c); + +/*! \brief + \param + + returns 1 if first charcter is white space +*/ +int utf8_char_whitespace(const utf8_char_t* c); + +/*! \brief + \param + + returns length of the string in bytes + size is number of charcter to count (0 to count until NULL term) +*/ +size_t utf8_string_length(const utf8_char_t* data, utf8_size_t size); +/*! \brief + \param +*/ +size_t utf8_char_copy(utf8_char_t* dst, const utf8_char_t* src); + +/*! \brief + \param + + returnes the number of utf8 charcters in a string givne the numbe of bytes + to coutn until the a null terminator, pass 0 for size +*/ +utf8_size_t utf8_char_count(const char* data, size_t size); +/*! \brief + \param + + returnes the length of the line in bytes triming not printable characters at the end +*/ +utf8_size_t utf8_trimmed_length(const utf8_char_t* data, utf8_size_t charcters); +/*! \brief + \param + + returns the length in bytes of the line including the new line charcter(s) + auto detects between windows(CRLF), unix(LF), mac(CR) and riscos (LFCR) line endings +*/ +size_t utf8_line_length(const utf8_char_t* data); +/*! \brief + \param + + returns number of chars to include before split +*/ +utf8_size_t utf8_wrap_length(const utf8_char_t* data, utf8_size_t size); + +/*! \brief + \param + + returns number of new lines in the string +*/ +int utf8_line_count(const utf8_char_t* data); + +/*! \brief + \param + size in/out. In the the max seize, out is the size read; + returns number of new lins in teh string +*/ +#define UFTF_DEFAULT_MAX_FILE_SIZE = (50 * 1024 * 1024); + +utf8_char_t* utf8_load_text_file(const char* path, size_t* size); + +/*! \brief + \param + + Compares 2 strings up to max len +*/ +#ifndef strnstr +char* strnstr(const char* string1, const char* string2, size_t len); +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/subprojects/gst-plugins-bad/sys/dwrite/libcaption/version.txt b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/version.txt new file mode 100644 index 0000000000..8e83874535 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/version.txt @@ -0,0 +1,3 @@ +Based on libcaption: https://github.com/szatmary/libcaption + +commit e8b6261090eb3f2012427cc6b151c923f82453db diff --git a/subprojects/gst-plugins-bad/sys/dwrite/libcaption/xds.c b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/xds.c new file mode 100644 index 0000000000..a9fae45523 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/xds.c @@ -0,0 +1,64 @@ +/**********************************************************************************************/ +/* The MIT License */ +/* */ +/* Copyright 2016-2017 Twitch Interactive, Inc. or its affiliates. All Rights Reserved. */ +/* */ +/* 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. */ +/**********************************************************************************************/ +// http://www.theneitherworld.com/mcpoodle/SCC_TOOLS/DOCS/CC_XDS.HTML#PR +#include "xds.h" +#include "caption.h" +#include + +void +xds_init (xds_t * xds) +{ + memset (xds, 0, sizeof (xds_t)); +} + +int +xds_decode (xds_t * xds, uint16_t cc) +{ + switch (xds->state) { + default: + case 0: + xds_init (xds); + xds->class_code = (cc & 0x0F00) >> 8; + xds->type = (cc & 0x000F); + xds->state = 1; + return LIBCAPTION_OK; + + case 1: + if (0x8F00 == (cc & 0xFF00)) { + xds->checksum = (cc & 0x007F); + xds->state = 0; + return LIBCAPTION_READY; + } + + if (xds->size < 32) { + xds->content[xds->size + 0] = (cc & 0x7F00) >> 8; + xds->content[xds->size + 1] = (cc & 0x007F); + xds->size += 2; + return LIBCAPTION_OK; + } + } + + xds->state = 0; + return LIBCAPTION_ERROR; +} diff --git a/subprojects/gst-plugins-bad/sys/dwrite/libcaption/xds.h b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/xds.h new file mode 100644 index 0000000000..e457a597c0 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/dwrite/libcaption/xds.h @@ -0,0 +1,48 @@ +/**********************************************************************************************/ +/* The MIT License */ +/* */ +/* Copyright 2016-2017 Twitch Interactive, Inc. or its affiliates. All Rights Reserved. */ +/* */ +/* 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. */ +/**********************************************************************************************/ +#ifndef LIBCAPTION_XDS_H +#define LIBCAPTION_XDS_H +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +typedef struct { + int state; + uint8_t class_code; + uint8_t type; + uint32_t size; + uint8_t content[32]; + uint8_t checksum; +} xds_t; + +void xds_init(xds_t* xds); +int xds_decode(xds_t* xds, uint16_t cc); + +#ifdef __cplusplus +} +#endif +#endif