Files
shaka-player/lib/cea/cea608_memory.js
T
Joey Parrish 38ce45dce5 cleanup: Fix nullability declarations
Cleanup imported from an internal Google migration process, courtesy
of Laura Harker.

Change-Id: I11de518eafe6008938589e5250bdcaf8151267e9
2021-06-22 21:03:20 +00:00

316 lines
7.8 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*! @license
* Shaka Player
* Copyright 2016 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.provide('shaka.cea.Cea608Memory');
goog.require('shaka.cea.CeaUtils');
goog.require('shaka.text.Cue');
goog.requireType('shaka.cea.ICaptionDecoder');
/**
* CEA-608 captions memory/buffer.
*/
shaka.cea.Cea608Memory = class {
/**
* @param {number} fieldNum Field number.
* @param {number} channelNum Channel number.
*/
constructor(fieldNum, channelNum) {
/**
* Buffer for storing decoded characters.
* @private @const {!Array<!Array<!shaka.cea.CeaUtils.StyledChar>>}
*/
this.rows_ = [];
/**
* Current row.
* @private {number}
*/
this.row_ = 1;
/**
* Number of rows in the scroll window. Used for rollup mode.
* @private {number}
*/
this.scrollRows_ = 0;
/**
* Field number.
* @private {number}
*/
this.fieldNum_ = fieldNum;
/**
* Channel number.
* @private {number}
*/
this.channelNum_ = channelNum;
/**
* @private {boolean}
*/
this.underline_ = false;
/**
* @private {boolean}
*/
this.italics_ = false;
/**
* @private {string}
*/
this.textColor_ = shaka.cea.CeaUtils.DEFAULT_TXT_COLOR;
/**
* @private {string}
*/
this.backgroundColor_ = shaka.cea.CeaUtils.DEFAULT_BG_COLOR;
this.reset();
}
/**
* Emits a closed caption based on the state of the buffer.
* @param {number} startTime Start time of the cue.
* @param {number} endTime End time of the cue.
* @return {?shaka.cea.ICaptionDecoder.ClosedCaption}
*/
forceEmit(startTime, endTime) {
const stream = `CC${(this.fieldNum_<< 1) | this.channelNum_ +1}`;
const topLevelCue = new shaka.text.Cue(
startTime, endTime, /* payload= */ '');
return shaka.cea.CeaUtils.getParsedCaption(
topLevelCue, stream, this.rows_, startTime, endTime);
}
/**
* Resets the memory buffer.
*/
reset() {
this.resetAllRows();
this.row_ = 1;
}
/**
* @return {number}
*/
getRow() {
return this.row_;
}
/**
* @param {number} row
*/
setRow(row) {
this.row_ = row;
}
/**
* @return {number}
*/
getScrollSize() {
return this.scrollRows_;
}
/**
* @param {number} scrollRows
*/
setScrollSize(scrollRows) {
this.scrollRows_ = scrollRows;
}
/**
* Adds a character to the buffer.
* @param {!shaka.cea.Cea608Memory.CharSet} set Character set.
* @param {number} b CC byte to add.
*/
addChar(set, b) {
// Valid chars are in the range [0x20, 0x7f]
if (b < 0x20 || b > 0x7f) {
return;
}
let char = '';
switch (set) {
case shaka.cea.Cea608Memory.CharSet.BASIC_NORTH_AMERICAN:
if (shaka.cea.Cea608Memory.CharSet.BasicNorthAmericanChars.has(b)) {
char =
shaka.cea.Cea608Memory.CharSet.BasicNorthAmericanChars.get(b);
} else {
// Regular ASCII
char = String.fromCharCode(b);
}
break;
case shaka.cea.Cea608Memory.CharSet.SPECIAL_NORTH_AMERICAN:
char =
shaka.cea.Cea608Memory.CharSet.SpecialNorthAmericanChars.get(b);
break;
case shaka.cea.Cea608Memory.CharSet.SPANISH_FRENCH:
// Extended charset does a BS over preceding char, 6.4.2 EIA-608-B.
this.eraseChar();
char =
shaka.cea.Cea608Memory.CharSet.ExtendedSpanishFrench.get(b);
break;
case shaka.cea.Cea608Memory.CharSet.PORTUGUESE_GERMAN:
this.eraseChar();
char =
shaka.cea.Cea608Memory.CharSet.ExtendedPortugueseGerman.get(b);
break;
}
if (char) {
const styledChar = new shaka.cea.CeaUtils.StyledChar(
char, this.underline_, this.italics_,
this.backgroundColor_, this.textColor_);
this.rows_[this.row_].push(styledChar);
}
}
/**
* Erases a character from the buffer.
*/
eraseChar() {
this.rows_[this.row_].pop();
}
/**
* Moves rows of characters.
* @param {number} dst Destination row index.
* @param {number} src Source row index.
* @param {number} count Count of rows to move.
*/
moveRows(dst, src, count) {
if (dst >= src) {
for (let i = count-1; i >= 0; i--) {
this.rows_[dst + i] = this.rows_[src + i].map((e) => e);
}
} else {
for (let i = 0; i < count; i++) {
this.rows_[dst + i] = this.rows_[src + i].map((e) => e);
}
}
}
/**
* Resets rows of characters.
* @param {number} idx Starting index.
* @param {number} count Count of rows to reset.
*/
resetRows(idx, count) {
for (let i = 0; i <= count; i++) {
this.rows_[idx + i] = [];
}
}
/**
* Resets the entire memory buffer.
*/
resetAllRows() {
this.resetRows(0, shaka.cea.Cea608Memory.CC_ROWS);
}
/**
* Erases entire memory buffer.
* Doesn't change scroll state or number of rows.
*/
eraseBuffer() {
this.row_ = (this.scrollRows_ > 0) ? this.scrollRows_ : 0;
this.resetAllRows();
}
/**
* @param {boolean} underline
*/
setUnderline(underline) {
this.underline_ = underline;
}
/**
* @param {boolean} italics
*/
setItalics(italics) {
this.italics_ = italics;
}
/**
* @param {string} color
*/
setTextColor(color) {
this.textColor_ = color;
}
/**
* @param {string} color
*/
setBackgroundColor(color) {
this.backgroundColor_ = color;
}
};
/**
* Maximum number of rows in the buffer.
* @const {number}
*/
shaka.cea.Cea608Memory.CC_ROWS = 15;
/**
* Characters sets.
* @const @enum {number}
*/
shaka.cea.Cea608Memory.CharSet = {
BASIC_NORTH_AMERICAN: 0,
SPECIAL_NORTH_AMERICAN: 1,
SPANISH_FRENCH: 2,
PORTUGUESE_GERMAN: 3,
};
/**
* Basic North American char set deviates from ASCII with these exceptions.
* @private @const {!Map<number, string>}
*/
shaka.cea.Cea608Memory.CharSet.BasicNorthAmericanChars = new Map([
[0x27, ''], [0x2a, 'á'], [0x5c, 'é'], [0x5c, 'é'], [0x5e, 'í'], [0x5f, 'ó'],
[0x60, 'ú'], [0x7b, 'ç'], [0x7c, '÷'], [0x7d, 'Ñ'], [0x7e, 'ñ'], [0x7f, '█'],
]);
/**
* Special North American char set.
* Note: Transparent Space is currently implemented as a regular space.
* @private @const {!Map<number, string>}
*/
shaka.cea.Cea608Memory.CharSet.SpecialNorthAmericanChars = new Map([
[0x30, '®'], [0x31, '°'], [0x32, '½'], [0x33, '¿'], [0x34, '™'], [0x35, '¢'],
[0x36, '£'], [0x37, '♪'], [0x38, 'à'], [0x39, ''], [0x3a, 'è'], [0x3b, 'â'],
[0x3c, 'ê'], [0x3d, 'î'], [0x3e, 'ô'], [0x3f, 'û'],
]);
/**
* Extended Spanish/Misc/French char set.
* @private @const {!Map<number, string>}
*/
shaka.cea.Cea608Memory.CharSet.ExtendedSpanishFrench = new Map([
[0x20, 'Á'], [0x21, 'É'], [0x22, 'Ó'], [0x23, 'Ú'], [0x24, 'Ü'], [0x25, 'ü'],
[0x26, ''], [0x27, '¡'], [0x28, '*'], [0x29, '\''], [0x2a, '─'], [0x2b, '©'],
[0x2c, '℠'], [0x2d, '·'], [0x2e, '“'], [0x2f, '”'], [0x30, 'À'], [0x31, 'Â'],
[0x32, 'Ç'], [0x33, 'È'], [0x34, 'Ê'], [0x35, 'Ë'], [0x36, 'ë'], [0x37, 'Î'],
[0x38, 'Ï'], [0x39, 'ï'], [0x3a, 'Ô'], [0x3b, 'Ù'], [0x3c, 'ù'], [0x3d, 'Û'],
[0x3e, '«'], [0x3f, '»'],
]);
/**
* Extended Portuguese/German/Danish char set.
* @private @const {!Map<number, string>}
*/
shaka.cea.Cea608Memory.CharSet.ExtendedPortugueseGerman = new Map([
[0x20, 'Ã'], [0x21, 'ã'], [0x22, 'Í'], [0x23, 'Ì'], [0x24, 'ì'], [0x25, 'Ò'],
[0x26, 'ò'], [0x27, 'Õ'], [0x28, 'õ'], [0x29, '{'], [0x2a, '}'], [0x2b, '\\'],
[0x2c, '^'], [0x2d, '_'], [0x2e, '|'], [0x2f, '~'], [0x30, 'Ä'], [0x31, 'ä'],
[0x32, 'Ö'], [0x33, 'ö'], [0x34, 'ß'], [0x35, '¥'], [0x36, '¤'], [0x37, '│'],
[0x38, 'Å'], [0x39, 'å'], [0x3a, 'Ø'], [0x3b, 'ø'], [0x3c, '┌'], [0x3d, '┐'],
[0x3e, '└'], [0x3f, '┘'],
]);