Compare commits

...

47 Commits

Author SHA1 Message Date
Punit Lodha
97b381a2b0 Switch to rustc 1.56.0 (#1404)
* Update CHANGES.TXT

* Update release flow

* use 1.56.0 compiler as 1.57.0 is bugged

Co-authored-by: PunitLodha <punitlodha@pm.com>
2021-12-15 17:03:45 +00:00
Punit Lodha
03b0749e91 Update release flow (#1403)
* Update CHANGES.TXT

* Update release flow

Co-authored-by: PunitLodha <punitlodha@pm.com>
2021-12-15 16:41:11 +00:00
Carlos Fernandez Sanz
7bcdd6729f Bump version 0.93 -> 0.94 2021-12-14 09:46:01 -08:00
Punit Lodha
3dd3d5f6aa Update CHANGES.TXT (#1402)
Co-authored-by: PunitLodha <punitlodha@pm.com>
2021-12-14 09:37:23 -08:00
Ritesh Maurya
ba37cc41c8 Update COMPILATION.MD (#1401)
Most of the users use Ubuntu 18.04 and later, so added the `libtesseract-dev`  rather than `tesseract-ocr-dev` in the bash command so new people don't run into any errors as the NOTE was written after the command.
2021-12-13 08:29:53 -08:00
Punit Lodha
6efa41a7e6 Extract 708 subs by default (#1398)
* Extract 708 subs by default

* fix fmt
2021-12-05 06:21:34 -08:00
Manolis Miminas
9b90c91f07 Update COMPILATION.MD (#1397)
Add missing slash character.
2021-12-01 12:16:07 +01:00
Carlos Fernandez Sanz
35936618e3 Display explicit message if text:text is found 2021-11-21 10:16:07 -08:00
Carlos Fernandez Sanz
e98a584e98 Exit build if rust part fails 2021-11-21 09:31:05 -08:00
Punit Lodha
1a8c8a86f3 Check start/end at param before encoding DVB subs (#1396) 2021-11-21 07:13:48 -08:00
Punit Lodha
57663b8cf1 Fix Carriage Return command (#1394)
* Fix Carriage Return command

* fix fmt

* Fix rollup
2021-11-20 09:29:19 -08:00
Willem
2b3d759e20 Update CHANGES.TXT
Add links to GH issues for 2 improvements in new version
2021-11-20 16:25:27 +00:00
Punit Lodha
ed1b5dddce Update windows build (#1393)
* Compile rust in a pre-build event

* Add msbuild to windows compilation docs

* Update CHANGES.TXT
2021-11-14 10:03:39 -08:00
Punit Lodha
86fede6af8 Fix negative delay bug, and other miscellaneous changes (#1392)
* Add message for detected version

* Update rust build scripts for windows

* Fix bug with negative delay values

* fix formatting
2021-11-13 06:38:50 -08:00
dependabot[bot]
68e6390c76 Bump actions/checkout from 2.3.4 to 2.4.0 (#1388)
Bumps [actions/checkout](https://github.com/actions/checkout) from 2.3.4 to 2.4.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2.3.4...v2.4.0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-10 07:03:06 +00:00
Hugh Mackworth
0ebeec4183 Repair Mac Build processes (#1390)
* Fix Mac Build processes

For all:
  Add Neon files to libpng for Apple Silicon
  Update compilation.md documentation

For autoconf:
  Make Linux and Mac Makefile.am and configure.ac identical
  Fix wrong location for zvbi/bcd.h in both Mac/Linux

For cmake::
  Include GPAC config for Darwin in Mac version

For mac/build.command:
  Update for new zvbi location

* Update CHANGES.TXT for Mac Build commit
2021-11-09 17:30:21 -08:00
Punit Lodha
8c10ded107 Add check for MSRV and update compilation docs (#1387)
* Add check for MSRV

* Update docs

* fix docs
2021-10-28 09:08:50 -07:00
Punit Lodha
3a1851f904 Make rust decoder default (#1375)
* Use rust by default and add -WITHOUT_RUST flag

* Fix for shell and autoconf builds

* change directory for version check

* change to  staticlib

* Update windows to build rust

* fix formatting

* add information about 708 decoder in version flag

* revert file mode to 644

* Use x86 for OCR releases

* fix flushing bug

* fix formatting

* update lib names

* remove bazel

* update changelog
2021-10-15 08:15:51 -07:00
Punit Lodha
50aceb45fb remove default BOM from windows (#1383)
* remove default BOM from windows

* update changelog
2021-10-08 15:30:54 -07:00
Willem
cad6b0495c Release flow improvements (#1381)
- Create .tar.gz for Linux that excludes the Windows & Git folders
- Create portable (zipped) version of CCExtractor (closes #1376)
2021-10-08 12:26:21 +02:00
Carlos Fernandez Sanz
c7ebd45d9f Version bump, 0.92 -> 0.93 2021-08-16 11:31:28 -07:00
Carlos Fernandez Sanz
77abe01885 Fix warning about using a keyword (new) as identifier 2021-08-16 11:30:59 -07:00
Punit Lodha
98cec31516 Rust updates:- Update documentation (#1374)
* Fix warning

* Update documentation

* Fix typo

* fmt
2021-08-14 08:44:23 -07:00
Jayesh Nirve
46b145a396 Update README.md (#1373) 2021-08-10 14:13:09 +02:00
Carlos Fernandez Sanz
ccf2a031e9 Bump version on Mac 0.91 -> 0.92 2021-08-10 04:24:39 -07:00
Carlos Fernandez Sanz
9784cd5bd1 Update CHANGES.TXT with last-minute Rust updates 2021-08-10 04:22:11 -07:00
Punit Lodha
5d8dc3b9eb Rust updates:- Add writers for transcripts and SAMI (#1372)
* add rust-iconv

* Add writer for transcipts and SAMI

* consistent import ordering
2021-08-10 04:21:22 -07:00
Carlos Fernandez Sanz
a42e847bcb Bump version 0.91 -> 0.92 2021-08-10 04:10:43 -07:00
Jayesh Nirve
b7a1dd1030 Update ISSUE_TEMPLATE.md (#1370) 2021-08-05 20:43:32 -07:00
Punit Lodha
b18e696c85 Rust updates: Added srt writer (#1368)
* pass -DENABLE_RUST to clang

* impl Default

* Update time str format

* Add SRT writer

* fmt
2021-08-03 13:59:31 -07:00
Willem
d58f078c38 Add missing DLL to the installer
Fixes #1367
2021-07-29 14:02:52 +02:00
PunitLodha
0bbdfc13ee Rust updates (#1364)
* add copy to screen

* Add tv_screen and more functions
2021-07-27 23:55:24 -07:00
Carlos Fernandez Sanz
5127da50d1 Push version 0.90 -> 0.91 2021-07-26 09:53:45 -07:00
PunitLodha
352f035214 [rust] Add Pen Presets and timing functions (#1363)
* add pen presets and timing functions

* fix typo

* fix formatting
2021-07-22 19:26:06 -07:00
PunitLodha
f04ba8d0c4 Rust updates (#1361)
* add handlers for CLW, HDW, TGW, DLW, and CR

* refactor rust code

* fix clippy warnings

* add ccxr_  prefix to rust functions

* Add SPA, SPC, SPL and CWx commands

* Add DSW and DFx commands

* Add more C0 and extended commands

* Use slice instead of sending whole packet and pos
2021-07-18 10:48:14 -07:00
Willem
1ea94d0b14 Update installer.wxs
Make ID's unique
2021-07-14 09:53:52 +02:00
Willem
7f99603859 Update installer.wxs
Add missing DLL's to the installation folder
2021-07-14 09:41:36 +02:00
Carlos Fernandez Sanz
3713283dfc Bump version 0.89 -> 0.90 2021-07-14 00:16:09 -07:00
PunitLodha
09129f1e63 [Rust] Add few commands and refactor the code (#1360)
* add handlers for CLW, HDW, TGW, DLW, and CR

* refactor rust code

* fix clippy warnings

* add ccxr_  prefix to rust functions

* Add SPA, SPC, SPL and CWx commands
2021-07-10 09:32:53 -07:00
PunitLodha
c56840ff2c Add functions to rust (#1358)
* add process_current_packet

* add process_service_block

* Add handle_G0 and G1 code sets

* remove unnecessary return

* Add C0 and C1 commands and their handlers
2021-07-04 11:11:03 -07:00
Willem
2a34bd99e6 [IMPROVEMENT] Automate release process for installer (#1357)
* Do not run push/pull request workflows for tags

* Stop including the old UI into artifacts for Widnows

* Introduce WiX installer and release flow
2021-06-28 14:18:33 -07:00
PunitLodha
c7886ed615 Add CI and docs for rust lib (#1355) 2021-06-27 17:58:51 +00:00
PunitLodha
948531a4be Update win_iconv path (#1356) 2021-06-26 11:43:32 -07:00
PunitLodha
022987c804 Add rust library (#1351)
* Add rust lib

* add steps for building rust lib

* use rust lib

* add conditional flag for rust

* use cargo config.toml

* add decoder module and update bindings

* use match instead of if else

* add target directory flag

* add env_logger

* use env_logger

* Process data first and then pass to safe function
2021-06-25 18:03:00 -07:00
PunitLodha
db6c852fae Add -DGPAC_CONFIG_LINUX for UNIX platforms (#1353) 2021-06-23 06:22:30 +00:00
PunitLodha
b793f16343 Update function declarations and naming style (#1350)
* Add declarations of functions and update names

* fix formating

* update function signature for dtvcc_process_data
2021-06-19 08:32:34 -07:00
carlos@ccextractor.org
ceaaa65a26 Remove confusing commits from build-static 2021-06-13 19:28:19 +00:00
75 changed files with 6832 additions and 1237 deletions

View File

@@ -2,6 +2,8 @@ Please prefix your issue with one of the following: [BUG], [PROPOSAL], [QUESTION
To get the version of CCExtractor, you can use `--version`.
If this issue is related to the flutter GUI, please make the issue on the GUI repo [here](https://github.com/CCExtractor/ccextractorfluttergui/issues/new)
Please check all that apply and **remove the ones that do not**.
In the necessary information section, if this is a regression (something that used to work does not work anymore), make sure to specify the last known working version.

View File

@@ -9,6 +9,9 @@ on:
- '**Makefile**'
- 'linux/**'
- 'package_creators/**'
- 'src/rust/**'
tags-ignore: # ignore push via new tag
- '*.*'
pull_request:
types: [opened, synchronize, reopened]
paths:
@@ -18,18 +21,20 @@ on:
- '**Makefile**'
- 'linux/**'
- 'package_creators/**'
- 'src/rust/**'
jobs:
build_shell:
runs-on: ubuntu-latest
steps:
- name: Install tesseract
run: sudo apt-get install libtesseract-dev
- uses: actions/checkout@v2.3.4
- uses: actions/checkout@v2.4.0
- name: build
run: ./build
working-directory: ./linux
- name: Display version information
run: ./linux/ccextractor --version
run: ./ccextractor --version
working-directory: ./linux
- name: Prepare artifacts
run: mkdir ./linux/artifacts
- name: Copy release artifact
@@ -41,22 +46,23 @@ jobs:
build_autoconf:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.4
- uses: actions/checkout@v2.4.0
- name: run autogen
run: ./autogen.sh
working-directory: ./linux
- name: configure
run: ./configure
run: ./configure --enable-debug
working-directory: ./linux
- name: make
run: make
working-directory: ./linux
- name: Display version information
run: ./linux/ccextractor --version
run: ./ccextractor --version
working-directory: ./linux
cmake:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.4
- uses: actions/checkout@v2.4.0
- name: cmake
run: mkdir build && cd build && cmake ../src
- name: build
@@ -67,7 +73,7 @@ jobs:
cmake_ocr_hardsubx:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.4
- uses: actions/checkout@v2.4.0
- name: dependencies
run: sudo apt update && sudo apt install libtesseract-dev libavformat-dev libswscale-dev
- name: cmake
@@ -77,13 +83,23 @@ jobs:
working-directory: build
- name: Display version information
run: ./build/ccextractor --version
bazel:
build_rust:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.4
- name: bazel build
working-directory: ./
run: bazel build //src:ccextractor --verbose_failures
- name: Display version information
working-directory: ./bazel-bin
run: ./src/ccextractor --version
- uses: actions/checkout@v2.4.0
- name: cache
uses: actions/cache@v2
with:
path: |
src/rust/.cargo/registry
src/rust/.cargo/git
src/rust/target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- name: build
run: cargo build
working-directory: ./src/rust

View File

@@ -3,106 +3,156 @@ name: Build CCExtractor on Windows
on:
push:
paths:
- '.github/workflows/build_windows.yml'
- '**.c'
- '**.h'
- 'windows/**'
- ".github/workflows/build_windows.yml"
- "**.c"
- "**.h"
- "windows/**"
tags-ignore: # ignore push via new tag
- "*.*"
pull_request:
types: [opened, synchronize, reopened]
paths:
- '.github/workflows/build_windows.yml'
- '**.c'
- '**.h'
- 'windows/**'
- ".github/workflows/build_windows.yml"
- "**.c"
- "**.h"
- "windows/**"
jobs:
build_non_ocr_release:
runs-on: windows-latest
steps:
- name: Check out repository
uses: actions/checkout@v2.3.4
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.0.2
- name: build Release
run: msbuild ccextractor.sln /p:Configuration=Release
working-directory: ./windows
- name: Display version information
run: ./ccextractorwin.exe --version
working-directory: ./windows/Release
- uses: actions/upload-artifact@v2
with:
name: CCExtractor Windows Non-OCR Release build
path: |
./windows/Release/ccextractorwin.exe
./windows/Release/ccextractorgui.exe
./windows/Release/*.dll
- name: Check out repository
uses: actions/checkout@v2.4.0
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.0.2
- name: Install llvm and clang
run: choco install llvm
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.56.0
override: true
- name: Install Win 10 SDK
uses: ilammy/msvc-dev-cmd@v1
- name: build Release
env:
LIBCLANG_PATH: "C:\\Program Files\\LLVM\\lib"
LLVM_CONFIG_PATH: "C:\\Program Files\\LLVM\\bin\\llvm-config"
CARGO_TARGET_DIR: "..\\..\\windows"
BINDGEN_EXTRA_CLANG_ARGS: -fmsc-version=0
run: msbuild ccextractor.sln /p:Configuration=Release /p:Platform=x64
working-directory: ./windows
- name: Display version information
run: ./ccextractorwin.exe --version
working-directory: ./windows/x64/Release
- uses: actions/upload-artifact@v2
with:
name: CCExtractor Windows Non-OCR Release build
path: |
./windows/x64/Release/ccextractorwin.exe
./windows/x64/Release/*.dll
build_non_ocr_debug:
runs-on: windows-latest
steps:
- name: Check out repository
uses: actions/checkout@v2.3.4
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.0.2
- name: build Debug
run: msbuild ccextractor.sln /p:Configuration=Debug
working-directory: ./windows
- name: Display version information
run: ./ccextractorwin.exe --version
working-directory: ./windows/Debug
- uses: actions/upload-artifact@v2
with:
name: CCExtractor Windows Non-OCR Debug build
path: |
./windows/Debug/ccextractorwin.exe
./windows/Debug/ccextractorwin.pdb
./windows/Debug/ccextractorgui.exe
./windows/Debug/*.dll
- name: Check out repository
uses: actions/checkout@v2.4.0
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.0.2
- name: Install llvm and clang
run: choco install llvm
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.56.0
override: true
- name: Install Win 10 SDK
uses: ilammy/msvc-dev-cmd@v1
- name: build Debug
env:
LIBCLANG_PATH: "C:\\Program Files\\LLVM\\lib"
LLVM_CONFIG_PATH: "C:\\Program Files\\LLVM\\bin\\llvm-config"
CARGO_TARGET_DIR: "..\\..\\windows"
BINDGEN_EXTRA_CLANG_ARGS: -fmsc-version=0
run: msbuild ccextractor.sln /p:Configuration=Debug /p:Platform=x64
working-directory: ./windows
- name: Display version information
run: ./ccextractorwin.exe --version
working-directory: ./windows/x64/Debug
- uses: actions/upload-artifact@v2
with:
name: CCExtractor Windows Non-OCR Debug build
path: |
./windows/x64/Debug/ccextractorwin.exe
./windows/x64/Debug/ccextractorwin.pdb
./windows/x64/Debug/*.dll
build_ocr_hardsubx_release:
runs-on: windows-latest
steps:
- name: Check out repository
uses: actions/checkout@v2.3.4
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.0.2
- name: build Release
run: msbuild ccextractor.sln /p:Configuration=Release-Full
working-directory: ./windows
- name: Display version information
run: ./ccextractorwinfull.exe --version
working-directory: ./windows/Release-Full
- uses: actions/upload-artifact@v2
with:
name: CCExtractor Windows OCR and HardSubX Release build
path: |
./windows/Release-Full/ccextractorwinfull.exe
./windows/Release-Full/*.dll
- uses: actions/upload-artifact@v2
with:
name: CCExtractor Windows OCR and HardSubX Release build
path: |
./windows/Release/ccextractorgui.exe
- name: Check out repository
uses: actions/checkout@v2.4.0
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.0.2
- name: Install llvm and clang
uses: egor-tensin/setup-clang@v1
with:
version: latest
platform: x86
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.56.0
override: true
target: i686-pc-windows-msvc
- name: Install Win 10 SDK
uses: ilammy/msvc-dev-cmd@v1
- name: build Release-Full
env:
LIBCLANG_PATH: "C:\\Program Files\\LLVM\\lib"
LLVM_CONFIG_PATH: "C:\\Program Files\\LLVM\\bin\\llvm-config"
CARGO_TARGET_DIR: "..\\..\\windows"
BINDGEN_EXTRA_CLANG_ARGS: -fmsc-version=0
run: msbuild ccextractor.sln /p:Configuration=Release-Full /p:Platform=Win32
working-directory: ./windows
- name: Display version information
run: ./ccextractorwinfull.exe --version
working-directory: ./windows/Release-Full
- uses: actions/upload-artifact@v2
with:
name: CCExtractor Windows OCR and HardSubX Release build
path: |
./windows/Release-Full/ccextractorwinfull.exe
./windows/Release-Full/*.dll
build_ocr_hardsubx_debug:
runs-on: windows-latest
steps:
- name: Check out repository
uses: actions/checkout@v2.3.4
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.0.2
- name: build Debug
run: msbuild ccextractor.sln /p:Configuration=Debug-Full
working-directory: ./windows
- name: Display version information
run: ./ccextractorwinfull.exe --version
working-directory: ./windows/Debug-Full
- uses: actions/upload-artifact@v2
with:
name: CCExtractor Windows OCR and HardSubX Debug build
path: |
./windows/Debug-Full/ccextractorwinfull.exe
./windows/Debug-Full/ccextractorwinfull.pdb
./windows/Debug-Full/*.dll
- uses: actions/upload-artifact@v2
with:
name: CCExtractor Windows OCR and HardSubX Debug build
path: |
./windows/Debug/ccextractorgui.exe
- name: Check out repository
uses: actions/checkout@v2.4.0
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.0.2
- name: Install llvm and clang
uses: egor-tensin/setup-clang@v1
with:
version: latest
platform: x86
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.56.0
override: true
target: i686-pc-windows-msvc
- name: Install Win 10 SDK
uses: ilammy/msvc-dev-cmd@v1
- name: build Debug-Full
env:
LIBCLANG_PATH: "C:\\Program Files\\LLVM\\lib"
LLVM_CONFIG_PATH: "C:\\Program Files\\LLVM\\bin\\llvm-config"
CARGO_TARGET_DIR: "..\\..\\windows"
BINDGEN_EXTRA_CLANG_ARGS: -fmsc-version=0
run: msbuild ccextractor.sln /p:Configuration=Debug-Full /p:Platform=Win32
working-directory: ./windows
- name: Display version information
run: ./ccextractorwinfull.exe --version
working-directory: ./windows/Debug-Full
- uses: actions/upload-artifact@v2
with:
name: CCExtractor Windows OCR and HardSubX Debug build
path: |
./windows/Debug-Full/ccextractorwinfull.exe
./windows/Debug-Full/ccextractorwinfull.pdb
./windows/Debug-Full/*.dll

View File

@@ -5,18 +5,47 @@ on:
- '.github/workflows/format.yml'
- 'src/**.c'
- 'src/**.h'
- 'src/rust/**'
tags-ignore: # ignore push via new tag
- '*.*'
pull_request:
types: [opened, synchronize, reopened]
paths:
- '.github/workflows/format.yml'
- 'src/**.c'
- 'src/**.h'
- 'src/rust/**'
jobs:
format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.4
- uses: actions/checkout@v2.4.0
- name: Format code
run: |
find src/ -type f -not -path "src/thirdparty/*" -not -path "src/lib_ccx/zvbi/*" -name '*.c' -not -path "src/GUI/icon_data.c" | xargs clang-format -i
git diff-index --quiet HEAD -- || (git diff && exit 1)
format_rust:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./src/rust
steps:
- uses: actions/checkout@v2.4.0
- name: cache
uses: actions/cache@v2
with:
path: |
src/rust/.cargo/registry
src/rust/.cargo/git
src/rust/target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
components: rustfmt, clippy
- name: rustfmt
run: cargo fmt --all -- --check
- name: clippy
run: cargo clippy -- -D warnings

82
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,82 @@
name: Upload releases
on:
release:
types:
- created
jobs:
build_windows:
runs-on: windows-latest
steps:
- name: Check out repository
uses: actions/checkout@v2.4.0
- name: Get the version
id: get_version
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\/v/}
shell: bash
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.0.2
- name: Install llvm and clang
uses: egor-tensin/setup-clang@v1
with:
version: latest
platform: x86
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.56.0
override: true
target: i686-pc-windows-msvc
- name: Install Win 10 SDK
uses: ilammy/msvc-dev-cmd@v1
- name: build Release-Full
env:
LIBCLANG_PATH: "C:\\Program Files\\LLVM\\lib"
LLVM_CONFIG_PATH: "C:\\Program Files\\LLVM\\bin\\llvm-config"
CARGO_TARGET_DIR: "..\\..\\windows"
BINDGEN_EXTRA_CLANG_ARGS: -fmsc-version=0
run: msbuild ccextractor.sln /p:Configuration=Release-Full /p:Platform=Win32
working-directory: ./windows
- name: Copy files to directory for installer
run: mkdir installer; cp ./Release-Full/ccextractorwinfull.exe ./installer; cp ./Release-Full/*.dll ./installer
working-directory: ./windows
- name: install WiX
run: dotnet tool install --global wix --version 4.0.0-preview.0 && wix extension -g add WixToolset.UI.wixext
- name: Make sure WiX works
run: wix --version && wix extension -g list
- name: Download Flutter GUI
run: ((Invoke-WebRequest -UseBasicParsing https://api.github.com/repos/CCExtractor/ccextractorfluttergui/releases/latest).Content | ConvertFrom-Json).assets | ForEach-Object {if ($_.name -eq "windows.zip") { Invoke-WebRequest -UseBasicParsing -Uri $_.browser_download_url -OutFile windows.zip}}
working-directory: ./windows
- name: Display contents of dir
run: ls
working-directory: ./windows
- name: Unzip Flutter GUI
run: Expand-Archive -Path ./windows.zip -DestinationPath ./installer
working-directory: ./windows
- name: Display installer folder contents
run: Get-ChildItem -Recurse ./installer
working-directory: ./windows
- name: Create portable zip
run: Compress-Archive -Path ./installer/* -DestinationPath ./CCExtractor_win_portable.zip
working-directory: ./windows
- name: Build installer
run: wix build -ext "$HOME\.wix\extensions\WixToolset.UI.wixext\4.0.0-preview.0\tools\WixToolset.UI.wixext.dll" -d "AppVersion=${{ steps.get_version.outputs.VERSION }}.0.0" -o CCExtractor.msi installer.wxs
working-directory: ./windows
- name: Upload as asset
uses: AButler/upload-release-assets@v2.0
with:
files: './windows/CCExtractor.msi;./windows/CCExtractor_win_portable.zip'
repo-token: ${{ secrets.GITHUB_TOKEN }}
create_linux_package:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.4.0
with:
path: ./ccextractor
- name: Create .tar.gz without git and windows folders
run: tar -pczf ./ccextractor_minimal.tar.gz --exclude "ccextractor/windows" --exclude "ccextractor/.git" ccextractor
- name: Upload as asset
uses: AButler/upload-release-assets@v2.0
with:
files: './ccextractor_minimal.tar.gz'
repo-token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -4,7 +4,7 @@ MAINTAINER = Marc Espie <espie@openbsd.org>
CATEGORIES = multimedia
COMMENT = closed caption subtitles extractor
HOMEPAGE = https://ccextractor.org
V = 0.89
V = 0.94
DISTFILES = ccextractor.${V:S/.//}-src.zip
MASTER_SITES = ${MASTER_SITE_SOURCEFORGE:=ccextractor/}
DISTNAME = ccextractor-$V

View File

@@ -38,7 +38,7 @@ This will extract the subtitles.
More usage information can be found on our website:
- [Using the command line tool](https://ccextractor.org/public/general/command_line_usage/)
- [Using the Windows GUI](https://ccextractor.org/public/general/win_gui_usage/)
- [Using the Flutter GUI](https://ccextractor.org/public/general/flutter_gui/)
You can also find the list of parameters and their brief description by running `ccextractor` without any arguments.

View File

@@ -1,3 +1,37 @@
0.94 (2021-12-14)
-----------------
- BOM is no longer enabled by default on windows platforms
- CEA-708: Rust decoder is now default instead of C decoder
- CEA-708 subs are now extracted by default
- New: Add check for Minimum supported rust version (MSRV) (#1387)
- Fix: Fix CEA-708 Carriage Return command implementation
- Fix: Fix bug with startat/endat parameter (#1396)
- Fix: Mac Build processes (#1390)
- Fix: Fix bug with negative delay parameter (#1365)
0.93 (2021-08-16)
-----------------
- Minor Rust updates (format, typos, docs)
- Updated GUI
0.92 (2021-08-10)
-----------------
- Rust updates: Added srt writer
- Rust updates:-Added writers for transcripts and SAMI
- Added missing DLL to Windows installer
- Updated Windows GUI
0.91 (2021-07-26)
-----------------
- More Rust in the 708 decoder (Add Pen Presets and timing functions)
- Updated GUI
0.90 (2021-07-14)
-----------------
- New installer (WiX based)
- New GUI (flutter based)
- More Rust (the 708 decoder is being rewritten)
0.89 (2021-06-13)
-----------------
- Fix: Fix broken links in README
@@ -56,7 +90,7 @@
- New: Add support for DVB inside .mkv
- Fix: Added -latrusmap Map Latin symbols to Cyrillic ones in special cases
of Russian Teletext files (issue #1086)
- Fix: Several OCR crashes
- Fix: Several OCR crashes
0.87 (2018-10-23)
-----------------
@@ -136,10 +170,10 @@
- New: Added tarball generation script.
- New: Added --analyzevideo. If present the video stream will be processed even if the
subtitles are in a different stream. This is useful when we want video information
(resolution, frame type, etc). -vides now implies this option too.
(resolution, frame type, etc). -vides now implies this option too.
[Note: Tentative - some possibly breaking changed were made for this, so if you
use it validate results]
- New: Added a GUI in the main CCExtractor binary (separate from the external GUIs
- New: Added a GUI in the main CCExtractor binary (separate from the external GUIs
such as CCExtractorGUI).
- New: A Python binding extension so it's possible to use CCExtractor's tools from
Python.
@@ -150,29 +184,29 @@
- New: FreeType-based text renderer (-out=spupng with teletext/EIA608).
- New: Upgrade library UTF8proc
- New: Upgrade library win_iconv
- New: Upgrade library zlib
- New: Upgrade library LibPNG
- New: Upgrade library zlib
- New: Upgrade library LibPNG
- New: Support for Source-Specific Multicast
- New: Added Travis CI support
- New: Added Travis CI support
- New: Made error messages clearer, less ambiguous
- Fix: Prevent the OCR being initialized more than once (happened on multiprogram and
PAT changes)
- Fix: Makefiles, build scripts, etc... everything updated and corrected for all
platforms.
-Fix: Proper line ending for .srt files from bitmaps.
- Fix: OCR corrections using grayscale before extracting texts.
-Fix: Proper line ending for .srt files from bitmaps.
- Fix: OCR corrections using grayscale before extracting texts.
- Fix: End timestamps in transcripts from DVB.
- Fix: Forcing -noru to cause deduplication in ISDB
- Fix: TS: Skip NULL packets
- Fix: TS: Skip NULL packets
- Fix: When NAL decoding fails, don't dump the whole decoded thing, limit to 160 bytes.
- Fix: Modify Autoconf scripts to generate tarball for mac from `/package_creators/tarball.sh`
- Fix: Modify Autoconf scripts to generate tarball for mac from `/package_creators/tarball.sh`
and include GUI files in tarball
- Fix: Started work on libGPAC upgrade.
- Fix: DVB subtitle not extracted if there's no display segment
- Fix: Heap corruption in add_ocrtext2str
- Fix: bug that caused -out=spupng sometimes crashes
- Fix: Checks for text before newlines on DVB subtitles
- Fix: OCR issue caused by separated dvb subtitle regions
- Fix: Checks for text before newlines on DVB subtitles
- Fix: OCR issue caused by separated dvb subtitle regions
- Fix: DVB crash on specific condition (!rect->ocr_text)
- Fix: DVB bug (Multiple-line subtitle; Missing last line)
- Fix: --sentencecap for teletext samples
@@ -219,7 +253,7 @@
0.84 (2016-12-16)
-----------------
- New: In Windows, both with and without-OCR binaries are bundled, since the OCR one causes problems due to
- New: In Windows, both with and without-OCR binaries are bundled, since the OCR one causes problems due to
dependencies in some system. So unless you need the OCR just use the non-OCR version.
- New: Added -sbs (sentence by sentence) for DVB output. Each frame in the output file contains a complete
sentence (experimental).
@@ -242,7 +276,7 @@
- Fix: Added detail in many error messages.
- Fix: Memory leaks in videos with XDS.
- Fix: Makefile compatibility issues with Raspberry pi.
- Fix: missing separation between WebVTT header and body.
- Fix: missing separation between WebVTT header and body.
- Fix: Stupid bug in M2TS that preventing it from working.
- Fix: OCR libraries dependencies for the release version in Windows.
- Fix: non-buffered reading from pipes.
@@ -289,7 +323,7 @@
- Fix: Timing in -ucla
- Fix: Timing in ISDB (some instances)
- Fix: "mfra" mp4 box weight changed to 1 (this helps with correct file format detection)
- Fix: Fix for TARGET File is null.
- Fix: Fix for TARGET File is null.
- Fix: Fixed SegFaults while parsing parameters (if mandatory parameter is not present in -outinterval, -codec or -nocodec)
- Fix: Crash when input small is too small
- Fix: Update some URLs in code (references to docs)
@@ -347,7 +381,7 @@
- CCExtractor can be used as library if compiled using cmake
- By default the Windows version adds BOM to generated UTF files (this is
because it's needed to open the files correctly) while all other
builds don't add it (because it messes with text processing tools).
builds don't add it (because it messes with text processing tools).
You can use -bom and -nobom to change the behaviour.
0.74 (2014-09-24)
@@ -386,7 +420,7 @@
------------------------
This is the first release that is part of Google's Summer of Code.
Anshul, Ruslan and Willem joined CCExtractor to work on a number of things
over the summer, and their work is already reaching the mainstream
over the summer, and their work is already reaching the mainstream
version of CCExtractor.
- Added a huge dictionary submitted by Matt Stockard.
@@ -419,7 +453,7 @@ version of CCExtractor.
0000101 is the default setting for transcripts
1110101 is the default for timed transcripts
1111001 is the default setting for -ucla
Make sure you use this parameter after others that might affect these
Make sure you use this parameter after others that might affect these
settings (-out, -ucla, -xds, -txt, -ttxt, ...)
- Fixed Negative timing Bug
@@ -437,7 +471,7 @@ version of CCExtractor.
- Started refactoring and clean-up.
- Fix: MPEG clock rollover (happens each 26 hours) caused a time
discontinuity.
- Windows GUI: Started work on HDHomeRun support. For now it just looks
- Windows GUI: Started work on HDHomeRun support. For now it just looks
for HDHomeRun devices. Lots of other things will arrive in the next
versions.
- Windows GUI: Some code refactoring, since the HDHomeRun support makes
@@ -454,7 +488,7 @@ version of CCExtractor.
a good test sample file...
- Color and fonts in PAC commands were ignored, fixed (Helen Buus).
- Added a new output format, spupng. It consists on one .png file
for each subtitle frame and one .xml with all the timing
for each subtitle frame and one .xml with all the timing
(Heleen Buus).
- Some fixes (Chris Small).
@@ -476,12 +510,12 @@ version of CCExtractor.
- Added -latin1 to select Latin 1 as encoding. Default is now
UTF-8 (-utf8 still exists but it's not needed).
- Added -ru1, which emulates a (non-existing in real life) 1 line
roll-up mode.
roll-up mode.
0.66 (2013-07-01)
-----------------
- Fixed bug in auto detection code that triggered a message
- Fixed bug in auto detection code that triggered a message
about file being auto of sync.
- Added -investigate_packets
The PMT is used to select the most promising elementary stream
@@ -490,39 +524,39 @@ version of CCExtractor.
manually, in case the CC location is not obvious from the PMT
contents. To assist looking for the right stream, the parameter
"-investigate_packets" will have CCExtractor look inside each
stream, looking for CC markers, and report the streams that
stream, looking for CC markers, and report the streams that
are likely to contain CC data even if it can't be determined from
their PMT entry.
- Added -datastreamtype to manually selecting a stream based on
its type instead of its PID. Useful if your recording program
always hides the caption under the stream type.
always hides the caption under the stream type.
- Added -streamtype so if an elementary stream is selected manually
for processing, the streamtype can be selected too. This can be
needed if you process, for example a stream that is declared as
for processing, the streamtype can be selected too. This can be
needed if you process, for example a stream that is declared as
"private MPEG" in the PMT, so CCExtractor can't tell what it is.
Usually you'll want -streamtype 2 (MPEG video) or -streamtype 6
(MPEG private data).
- PMT content listing improved, it now shows the stream type for
more types.
- Fixes in roll-up, cursor was being moved to column 1 if a
- Fixes in roll-up, cursor was being moved to column 1 if a
RU2, RU3 or RU4 was received even if already in roll-up mode.
- Added -autoprogram. If a multiprogram TS is processed and
- Added -autoprogram. If a multiprogram TS is processed and
-autoprogram is used, CCExtractor will analyze all PMTs and use
the first program that has a suitable data stream.
- Timed transcript (ttxt) now also exports the caption mode
(roll-up, paint-on, etc.) next to each line, as it's useful to
- Timed transcript (ttxt) now also exports the caption mode
(roll-up, paint-on, etc.) next to each line, as it's useful to
detect things like commercials.
- Content Advisory information from XDS is now decoded if it's
transmitted in "US TV parental guidelines" or "MPA".
Other encoding such as Canada's are not supported yet due
transmitted in "US TV parental guidelines" or "MPA".
Other encoding such as Canada's are not supported yet due
to lack of samples.
- Copy Management information from XDS is now decoded.
- Added -xds. If present and export format is timed transcript
(only), XDS information will be saved to file (same file as the
transcript, with XDS being clearly marked). Note that for now
all XDS data is exported even if it doesn't change, so the
all XDS data is exported even if it doesn't change, so the
transcript file will be significantly larger.
- Added some PaintOn support, at least enough to prevent it
- Added some PaintOn support, at least enough to prevent it
from breaking things when the other modes are used.
- Removed afd_data() warning. AFD doesn't carry any caption related
data. AFD still detected in code in case we want to do something
@@ -540,21 +574,21 @@ version of CCExtractor.
calculated distance, the maximum allowed distance, and whether
the strings are ultimately considered equivalent or not, i.e.
the calculated distance is less or equal than the max allowed.
-levdistmincnt value: Minimum distance we always allow
regardless of the length of the strings. Default 2. This means
that if the calculated distance is 0, 1 or 2, we consider the
-levdistmincnt value: Minimum distance we always allow
regardless of the length of the strings. Default 2. This means
that if the calculated distance is 0, 1 or 2, we consider the
strings to be equivalent.
-levdistmaxpct value: Maximum distance we allow, as a
percentage of the shortest string length. Default 10%. For
example, consider a comparison of one string of 30 characters
and one of 60 characters. We want to determine whether the
first 30 characters of the longer string are more or less the
same as the shortest string, i.e. whether the longest string
is the shortest one plus new characters and maybe some
corrections. Since the shortest string is 30 characters and
the default percentage is 10%, we would allow a distance of
-levdistmaxpct value: Maximum distance we allow, as a
percentage of the shortest string length. Default 10%. For
example, consider a comparison of one string of 30 characters
and one of 60 characters. We want to determine whether the
first 30 characters of the longer string are more or less the
same as the shortest string, i.e. whether the longest string
is the shortest one plus new characters and maybe some
corrections. Since the shortest string is 30 characters and
the default percentage is 10%, we would allow a distance of
up to 3 between the first 30 characters.
- Added -lf : Use UNIX line terminator (LF) instead of Windows (CRLF).
- Added -lf : Use UNIX line terminator (LF) instead of Windows (CRLF).
- Added -noautotimeref: Prevent UTC reference from being auto set from
the stream data.
@@ -564,7 +598,7 @@ version of CCExtractor.
- Added end timestamps in timed transcripts
- Added support for SMPTE (patch by John Kemp)
- Initial support for MPEG2 video tracks inside MP4 files (thanks a
lot to GPAC's Jean who assisted in analyzing the sample and
lot to GPAC's Jean who assisted in analyzing the sample and
doing the required changes in GPAC).
- Improved MP4 auto detection
- Support for PCR if PTS is not available (needed for some teletext
@@ -590,7 +624,7 @@ version of CCExtractor.
data (bypassing detections).
- Added -ru2 and -ru3 to limit the number of visible lines in roll-up
captions (bypassing whatever the broadcast says).
- Added support for a .hex (hexadecimal) dump of data.
- Added support for a .hex (hexadecimal) dump of data.
- Added support for wtv in Windows. This is done by using a new program
(wtvccdump.exe) and a new DirectShow filter (CCExtractorDump.dll) that
process the .wtv using DirecShow's filters and export the line 21 data
@@ -601,9 +635,9 @@ version of CCExtractor.
0.63 (2012-08-17)
-----------------
- Telext support added, by integrating Petr Kutalek's telxcc. Integration is
still quite basic (there's equivalent code from both CCExtractor and
telxcc) and some clean up is needed, but it works. Petr has announced that
he's abandoning telxcc so further development will happen directly in
still quite basic (there's equivalent code from both CCExtractor and
telxcc) and some clean up is needed, but it works. Petr has announced that
he's abandoning telxcc so further development will happen directly in
CCExtractor.
- Some bug fixes, as usual.
@@ -613,14 +647,14 @@ version of CCExtractor.
Mac users that sent this.
- Hauppauge mode now uses PES timing, needed for files that don't have
caption data during all the video (such as in commercial breaks).
- Added -mp4 and -in:mp4 to force the input to be processed as MP4.
- Added -mp4 and -in:mp4 to force the input to be processed as MP4.
- CC608 data embedded in a separate stream (as opposed as in the video
stream itself) in MP4 files is now supported (not heavily tested).
stream itself) in MP4 files is now supported (not heavily tested).
This should be rather useful since closed captioned files from iTunes
use this format.
- More CEA-708 work. The debugger is now able to dump the "TV" contents for
the first time. Also, a .srt can be generated, however timing is not quite
good yet (still need to figure out why).
the first time. Also, a .srt can be generated, however timing is not quite
good yet (still need to figure out why).
- Added -svc (or --service) to select the CEA-708 services to be processed.
For example, -svc 1,2 will process the primary and secondary language
services. Valid values are 1-63, where 1 is the primary language, 2 is
@@ -635,9 +669,9 @@ version of CCExtractor.
- Fix: GCC 3.4.4 can now build CCExtractor.
- Fix: Damaged TS packets (those that come with 'error in transport' bit
on) are now skipped.
- Fix: Part of the changes for MP4 support (CC packets buffering in
particular) broke some stuff for other files, causing at least very
annoying character duplication. We hope we've fixed it without breaking
- Fix: Part of the changes for MP4 support (CC packets buffering in
particular) broke some stuff for other files, causing at least very
annoying character duplication. We hope we've fixed it without breaking
anything but please report).
- Some non-interesting cleanup.
@@ -648,13 +682,13 @@ version of CCExtractor.
code, the stream must be a file (no streaming), etc.
- Fix: The Windows version was writing text files with double \r.
- Fix: Closed captions blocks with no data could cause a crash.
- Fix: -noru (to generate files without duplicate lines in
- Fix: -noru (to generate files without duplicate lines in
roll-up) was broken, with complete lines being missing.
- Fix: bin format not working as input.
- Fix: bin format not working as input.
0.59 (2011-10-07)
-----------------
- More AVC/H.264 work. pic_order_cnt_type != 0 will be processed now.
- More AVC/H.264 work. pic_order_cnt_type != 0 will be processed now.
- Fix: Roll-up captions with interruptions for Text (with ResumeTextDisplay
in the middle of the caption data) were missing complete lines.
- Added a timed text transcript output format, probably only useful for
@@ -677,7 +711,7 @@ version of CCExtractor.
- Added -stdout => If used, the captions will be sent to stdout (console)
instead of file. Combined with -, CCExtractor can work as a filter in
a larger process, receiving the stream from stdin and sending the
captions to stdout.
captions to stdout.
- Some code clean up, minor refactoring.
- Teletext detection (not yet processing).
@@ -686,20 +720,20 @@ version of CCExtractor.
- Implemented new PTS based mode to order the caption information
of AVC/H.264 data streams. The old pic_order_cnt_lsb based method
is still available via the -poc or --usepicorder command switches.
- Removed a couple of those annoying "Impossible!" error messages
- Removed a couple of those annoying "Impossible!" error messages
that appears when processing some (possibly broken, unsure) files.
- Added -nots --notypesettings to prevent italics and underline
- Added -nots --notypesettings to prevent italics and underline
codes from being displayed.
- Note to those not liking the paragraph symbol being used for the
- Note to those not liking the paragraph symbol being used for the
music note: Submit a VALID replacement in latin-1.
- Added preliminary support for multiple program TS files. The
- Added preliminary support for multiple program TS files. The
parameter --program-number (or -pn) will let you choose which
program number to process. If no number is passed and the TS
program number to process. If no number is passed and the TS
file contains more than one, CCExtractor will display a list of
found programs and terminate.
- Added support (basic, because I only received one sample) for some
Hauppauge cards that save CC data in their own format. Use the
parameter -haup to enable it (CCExtractor will display a notice
parameter -haup to enable it (CCExtractor will display a notice
if it thinks that it's processing a Hauppauge capture anyway).
- Fixed bug in roll-up.
- More AVC work, now TS files from echostar that provided garbled
@@ -709,7 +743,7 @@ version of CCExtractor.
0.57 (2010-12-16)
-----------------
- Bug fixes in the Windows version. Some debug code was unintentionally
left in the released version.
left in the released version.
0.56 (2010-12-09)
-----------------
@@ -726,10 +760,10 @@ version of CCExtractor.
- Start implementation of EIA-708 decoding (not active yet).
- Add -gt / --goptime switch to use GOP timing instead of PTS timing.
- Start implementation of AVC/H.264 decoding (not active yet).
- Fixed: The basic problem is that when 24fps movie film gets converted to 30fps NTSC
they repeat every 4th frame. Some pics have 3 fields of CC data with field 3 CC data
belongs to the same channel as field 1. The following pics have the fields reversed
because of the odd number of fields. I used top_field_first to tell when the channels
- Fixed: The basic problem is that when 24fps movie film gets converted to 30fps NTSC
they repeat every 4th frame. Some pics have 3 fields of CC data with field 3 CC data
belongs to the same channel as field 1. The following pics have the fields reversed
because of the odd number of fields. I used top_field_first to tell when the channels
are reversed. See Table 6-1 of the SCTE 20 [Paul Fernquist]
0.54 (2009-04-16)
@@ -739,9 +773,9 @@ version of CCExtractor.
- Improve synchronization of captions for source files with
jumps in their time information or gaps in the caption
information.
- [R. Abarca] Changed Mac script, it now compiles/link
everything from the /src directory.
- It's now possible to have CCExtractor add credits
- [R. Abarca] Changed Mac script, it now compiles/link
everything from the /src directory.
- It's now possible to have CCExtractor add credits
automatically.
- Added a feature to add start and end messages (for credits).
See help screen for details.
@@ -762,13 +796,13 @@ version of CCExtractor.
for Raw Captions With Time). This new format
allows one file to contain all the available
closed caption data instead of just one stream.
- Added --no_progress_bar to disable status
- Added --no_progress_bar to disable status
information (mostly used when debugging, as the
progress information is annoying in the middle
of debug logs).
- The Windows GUI was reported to freeze in some
- The Windows GUI was reported to freeze in some
conditions. Fixed.
- The Windows GUI is now targeted for .NET 2.0
- The Windows GUI is now targeted for .NET 2.0
instead of 3.5. This allows Windows 2000 to run
it (there's not .NET 3.5 for Windows 2000), as
requested by a couple of key users.
@@ -776,17 +810,17 @@ version of CCExtractor.
0.51 (unreleased)
-----------------
- Removed -autopad and -goppad, no longer needed.
- In preparation to a new binary format we have
renamed the current .bin to .raw. Raw files
- In preparation to a new binary format we have
renamed the current .bin to .raw. Raw files
have only CC data (with no header, timing, etc.).
- The input file format (when forced) is now
specified with
specified with
-in=format
such as -in=ts, -in=raw, -in=ps ...
The old switches (-ts, -ps, etc.) still work.
The only exception is -bin which has been removed
(reserved for the new binary format). Use
-in=raw to process a raw file.
-in=raw to process a raw file.
- Removed -d, which when produced a raw file used
a DVD format. This has been merged into a new
output type "dvdraw". So now instead of using
@@ -795,7 +829,7 @@ version of CCExtractor.
- Removed --noff
- Added gui_mode_reports for frontend communications,
see related file.
- Windows GUI rewritten. Source code now included,
- Windows GUI rewritten. Source code now included,
too.
- [Volker] Dish Network clean-up
@@ -808,12 +842,12 @@ version of CCExtractor.
0.49 (2008-12-10)
-----------------
- [Volker] Major MPEG parser rework. Code much
cleaner now.
cleaner now.
- Some stations transmit broken roll-up captions,
and for some reason don't send CRs but RUs...
Added work-around code to make captions readable.
- Started work on EIA-708 (DTV). Right now you can
add -debug-708 to get a dump of the 708 data.
add -debug-708 to get a dump of the 708 data.
An actually useful decoder will come soon.
- Some of the changes MIGHT HAVE BROKEN MythTV's
code. I don't use MythTV myself so I rely on
@@ -829,9 +863,9 @@ version of CCExtractor.
can now process files that are being recorded
at the same time.
- [Volker] Added a new DVR-MS loop - this is
- [Volker] Added a new DVR-MS loop - this is
completely new, DVR-MS specific code, so we no
longer use the generic MPEG code for DVR-MS.
longer use the generic MPEG code for DVR-MS.
DVR-MS should (or will be eventually at least)
be as reliable as TS.
Note: For now, it's only ATSC recordings, not
@@ -850,11 +884,11 @@ version of CCExtractor.
new options.
- Added -lg --largegops
From the help screen:
Each Group-of-Picture comes with timing
information. When this info is too separate
(for example because there are a lot of
frames in a GOP) ccextractor may prefer not
to use GOP timing. Use this option is you
Each Group-of-Picture comes with timing
information. When this info is too separate
(for example because there are a lot of
frames in a GOP) ccextractor may prefer not
to use GOP timing. Use this option is you
need ccextractor to use GOP timing in large
GOPs.
@@ -873,8 +907,8 @@ version of CCExtractor.
0.43 (2008-06-20)
-----------------
- Fixed a bug in the read loop (no less)
that caused some files to fail when
reading without buffering (which is
that caused some files to fail when
reading without buffering (which is
the default in the Linux build).
- Several improvements in the GUI, such as
saving current options as default.
@@ -891,8 +925,8 @@ version of CCExtractor.
-----------------
- Default output is now .srt instead of .bin,
use -raw if you need the data dump instead of
.srt.
- Added -trim, which removes blank spaces at
.srt.
- Added -trim, which removes blank spaces at
the left and rights of each line in .srt.
Note that those spaces are there to help
deaf people know if the person talking is
@@ -902,8 +936,8 @@ version of CCExtractor.
0.40 (2008-05-20)
-----------------
- Fixed a bug in the sanity check function
that caused the Myth branch to abort.
- Fixed a bug in the sanity check function
that caused the Myth branch to abort.
- Fixed the OSX build script, it needed a
new #define to work.
@@ -913,30 +947,30 @@ version of CCExtractor.
have no time information. Also, if in roll-up
mode there will be no repeated lines.
- Lots of changes in the MPEG parser, most of
them submitted by Volker Quetschke.
them submitted by Volker Quetschke.
- Fixed a bug in the CC decoder that could cause
the first line not to be cleared in roll-up
mode.
mode.
- CCExtractor can now follow number sequences in
file names, by suffixing the name with +.
For example,
DVD0001.VOB+
DVD0001.VOB+
means DVD0001.VOB, DVD0002.VOB, etc. This works
for all files, so part001.ts+ does what you
could expect.
- Added -90090 which changes the clock frequency
from the MPEG standard 90000 to 90090. It
from the MPEG standard 90000 to 90090. It
*could* (remains to be seen) help if there are
timing issues.
timing issues.
- Better support for Tivo files.
- By default ccextractor now considers the whole
input file list a one large file, instead of
several, independent, video files. This has
been changed because most programs (for example
DVDDecrypt) just cut the files by size.
If you need the old behaviour (because you
DVDDecrypt) just cut the files by size.
If you need the old behaviour (because you
actually edited the video files and want to
join the subs), use -ve.
@@ -954,7 +988,7 @@ version of CCExtractor.
that have been added because old behaviour was
annoying to most people: _1 and _2 at the end
of the output file names is now added ONLY if
-12 is used (i.e. when there are two output
-12 is used (i.e. when there are two output
files to produce). So
ccextractor -srt sopranos.mpg
@@ -1015,7 +1049,7 @@ version of CCExtractor.
Alan
Tony
So you get
So you get
You better respect
this robe, Alan.
@@ -1024,7 +1058,7 @@ version of CCExtractor.
have a different spelling file per TV
show, or a large file with a lot of
words, etc.
- ccextractor has been reported to
- ccextractor has been reported to
compile and run on Mac with a minor
change in the build script, so I've
created a mac directory with the
@@ -1038,17 +1072,17 @@ version of CCExtractor.
-----------------
- Added -scr or --screenfuls, to select the
number of screenfuls ccextractor should
write before exiting. A screenful is
write before exiting. A screenful is
a change of screen contents caused by
a CC command (not new characters). In
practice, this means that for .srt each
group of lines is a screenful, except when
using -dru (which produces a lot of
using -dru (which produces a lot of
groups of lines because each new character
produces a new group).
- Completed tables for all encodings.
- Fixed bug in .srt related to milliseconds
in time lines.
in time lines.
- Font colors are back for .srt (apparently
some programs do support them after all).
Use -nofc or --nofontcolor if you don't
@@ -1057,7 +1091,7 @@ version of CCExtractor.
0.32 (unreleased)
-----------------
- Added -delay ms, which adds (or subtracts)
a number of milliseconds to all times in
a number of milliseconds to all times in
.srt/.sami files. For example,
-delay 400
@@ -1088,8 +1122,8 @@ version of CCExtractor.
- Fix in extended char decoding, I wasn't
replacing the previous char.
- When a sequence code was found before
having a PTS, reported time was
undefined.
having a PTS, reported time was
undefined.
0.29 (unreleased)
-----------------
@@ -1114,7 +1148,7 @@ version of CCExtractor.
0.26 (unreleased)
-----------------
- Added -gp (or -goppad) to make ccextractor use
GOP timing. Try it for non TS files where
GOP timing. Try it for non TS files where
subs start OK but desync as the video advances.
0.25 (unreleased)
@@ -1123,7 +1157,7 @@ version of CCExtractor.
-nomyth to prevent the MytvTV code path to be
called. I've seen apparently correct files that
make MythTV's MPEG decoder to choke. So, if it
doesn't work correctly automatically: Try
doesn't work correctly automatically: Try
-nomyth and -myth. Hopefully one of the two
options will work.
@@ -1136,7 +1170,7 @@ version of CCExtractor.
- Reworked input buffer code, faster now.
- Completed MythTV's MPEG decoder for Program Streams,
which results in better processing of some specific
files.
files.
- Automatic file format detection for all kind of
files and closed caption storage method. No need to
tell ccextractor anything about your file (but you
@@ -1145,10 +1179,10 @@ version of CCExtractor.
0.22 (2007-05-15)
-----------------
- Added text mode handling into decoder, which gets rids
- Added text mode handling into decoder, which gets rids
of junk when text mode data is present.
- Added support for certain (possibly non standard
compliant) DVDs that add more captions block in a
compliant) DVDs that add more captions block in a
user data block than they should (such as Red October).
- Fix in roll-up init code that caused the previous popup
captions not to be written to disk.
@@ -1159,13 +1193,13 @@ version of CCExtractor.
-----------------
- Unicode should be decent now.
- Added support for Hauppauge PVR 250 cards, and (possibly)
many others (bttv) with the same closed caption recording
many others (bttv) with the same closed caption recording
format.
This is the result of hacking MythTV's MPEG parser into
CCExtractor. Integration is not very good (to put it
midly) but it seems to work. Depending on the feedback I
may continue working on this or just leave it 'as it'
(good enough).
(good enough).
If you want to process a file generated by one of these
analog cards, use -myth. This is essential as it will
make the program take a totally different code path.
@@ -1175,10 +1209,10 @@ version of CCExtractor.
0.19 (2007-05-03)
-----------------
- Work on Dish Network streams, timing was completely broken.
- Work on Dish Network streams, timing was completely broken.
It's fixed now at least for the samples I have, if it's not
completely fixed let me know. Credit for this goes to
Jack Ha who sent me a couple of samples and a first
Jack Ha who sent me a couple of samples and a first
implementation of a semi working-fix.
- Added support for several input files (see help screen for
details).

View File

@@ -17,16 +17,17 @@ git clone https://github.com/CCExtractor/ccextractor.git
Debian:
```bash
sudo apt-get install -y libglew-dev libglfw3-dev cmake gcc libcurl4-gnutls-dev tesseract-ocr tesseract-ocr-dev libleptonica-dev
sudo apt-get install -y libglew-dev libglfw3-dev cmake gcc libcurl4-gnutls-dev tesseract-ocr libtesseract-dev libleptonica-dev clang libclang-dev
```
RHEL:
```bash
yum install -y glew-devel glfw-devel cmake gcc libcurl-devel tesseract-devel leptonica-devel
yum install -y glew-devel glfw-devel cmake gcc libcurl-devel tesseract-devel leptonica-devel clang
```
Rust 1.54 or above is also required.[Install Rust](https://www.rust-lang.org/tools/install). Check specific compilation methods below, on how to compile without rust
**Note:** On Ubuntu Version 18.04 (Bionic) and (probably) later, install `libtesseract-dev` rather than `tesseract-ocr-dev`, which does not exist anymore.
**Note:** On Ubuntu Version 18.04 (Bionic) and later, `libtesseract-dev` is installed rather than `tesseract-ocr-dev`, which does not exist anymore.
**Note:** On Ubuntu Version 14.04 (Trusty) and earlier, you should build leptonica and tesseract from source
@@ -43,6 +44,9 @@ cd ccextractor/linux
# compile without debug flags
./build
# compile without rust
./build -without-rust
# compile with debug info
./builddebug
@@ -56,7 +60,7 @@ cd ccextractor/linux
sudo apt-get install autoconf #Dependency to generate configuration script
cd ccextractor/linux
./autogen.sh
./configure
./configure # OR ./configure --without-rust
make
# test your build
@@ -70,14 +74,12 @@ sudo make install
```bash
#Create and navigate to directory where you want to store built files
cd ccextractor/
mkdir build
cd build
#Generate makefile using cmake and then compile
cmake ../src/
cmake ../src/ # options here
make
# test your build
@@ -87,13 +89,16 @@ make
sudo make install
```
`cmake` also accepts the argument `-DWITH_OCR=ON` to enable OCR.
`cmake` also accepts the options:
`-DWITH_OCR=ON` to enable OCR
`-DWITHOUT_RUST=ON` to disable rust.
`-DWITH_HARDSUBX=ON` to enable burned-in subtitles
### Compiling with GUI:
To build CCExtractor with a gui you will additionally need to install [GLEW](http://glew.sourceforge.net/build.html) and [GLFW](http://www.glfw.org/docs/latest/compile.html)
To build CCExtractor with a GUI, you will additionally need to install [GLEW](http://glew.sourceforge.net/build.html) and [GLFW](http://www.glfw.org/docs/latest/compile.html)
In order to compile it you'll need to configure it using autoconf by passing the `-with-gui` option.
In order to compile it, you'll need to configure it using autoconf by passing the `-with-gui` option.
```bash
./autogen.sh
@@ -108,16 +113,18 @@ Once set up you can run the GUI interface from the terminal `./ccextractorGUI`
## macOS
1. Make sure all the dependencies are met. They can be installed via Homebrew as
1. Make sure all the dependencies are met. Decide if you want OCR; if so, you'll need to install tesseract and leptonica.
Dependencies can be installed via Homebrew as:
```bash
brew install pkg-config
brew install autoconf automake libtool
# optional if you want OCR:
brew install tesseract
brew install leptonica
```
Use pkg-config to verify tesseract and leptonica dependencies, e.g.
If configuring OCR, use pkg-config to verify tesseract and leptonica dependencies, e.g.
```bash
pkg-config --exists --print-errors tesseract
@@ -130,17 +137,7 @@ pkg-config --exists --print-errors lept
```bash
cd ccextractor/mac
./build.command OCR
# test your build
./ccextractor
```
If you don't want the OCR capabilities, then you don't need to configure the tesseract and leptonica packages, and build it with just
```bash
cd ccextractor/mac
./build.command
./build.command # OR ./build.command OCR
# test your build
./ccextractor
@@ -150,26 +147,29 @@ cd ccextractor/mac
```bash
#Create and navigate to directory where you want to store built files
cd ccextractor/
mkdir build
cd build
#Generate makefile using cmake and then compile
cmake ../src/
cmake ../src/ # options here
make
# test your build
./ccextractor
```
`cmake` also accepts the options:
`-DWITH_OCR=ON` to enable OCR
`-DWITHOUT_RUST=ON` to disable rust.
`-DWITH_HARDSUBX=ON` to enable burned-in subtitles
#### Standard compilation through Autoconf scripts:
```bash
cd ccextractor/mac
./autogen.sh
./configure
./configure # OR ./configure --without-rust
make
# test your build
@@ -185,17 +185,19 @@ brew install glfw
brew install glew
```
In order to compile it you'll need to configure it using autoconf by passing the `-with-gui` option.
In order to compile it, you'll need to configure it using autoconf by passing the `-with-gui` option.
```bash
./autogen.sh
./configure --with-gui
./configure --with-gui #OR .configure --with-gui --without-rust
make
```
Once set up you can run the GUI interface from the terminal `./ccextractorGUI`
Once set up, you can run the GUI interface from the terminal `./ccextractorGUI`
## Windows
Dependencies are clang and rust. To enable OCR, rust i686-pc-windows-msvc target should be installed
Note: Following screenshots and steps are based on Visual Studio 2017, but they should be more or less same for other versions.
1.Open `windows/` directory to locate `ccextractor.vcxproj`, `ccextractorGUI.vcxproj` (blue arrows) and `ccextractor.sln` (red arrow).
@@ -234,6 +236,22 @@ cmake ../src/ -G "Visual Studio 14 2015"
cmake --build . --config Release --ccextractor
```
### Using MSBuild
Run the following command in `windows/` directory
```bash
msbuild ccextractor.sln /p:Configuration=Release /p:Platform=x64
```
Different configuration options are,
| Configuration | Platform | Rust target required |
| ------------- |:-------------:| -----:|
| Release | x64 | default |
| Debug | x64 | default |
| Release-Full(OCR) | Win32 | i686-pc-windows-msvc |
| Debug-Full(OCR) | Win32 | i686-pc-windows-msvc |
## Building Installation Packages
### Arch Linux

View File

@@ -35,5 +35,8 @@ cmake -DWITH_SHARING=ON ../src/
If you want to build CCExtractor with HARDSUBX support
cmake -DWITH_HARDSUBX=ON ../src/
If you want to build CCExtractor with rust disabled you need to pass
cmake -DWITHOUT_RUST=ON ../src/
Hint for looking all the things you want to set from outside
cmake -LAH ../src/

2
linux/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
libccx_rust.a
rust

View File

@@ -1,5 +1,5 @@
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4/
bin_PROGRAMS = ccextractor
ccextractor_SOURCES = \
@@ -262,7 +262,7 @@ ccextractor_SOURCES = \
../src/thirdparty/lib_hash/sha2.h \
../src/thirdparty/protobuf-c/protobuf-c.c \
../src/thirdparty/protobuf-c/protobuf-c.h \
../src/thirdparty/zvbi/bcd.h \
../src/lib_ccx/zvbi/bcd.h \
../src/lib_ccx/zvbi/bit_slicer.c \
../src/lib_ccx/zvbi/bit_slicer.h \
../src/lib_ccx/zvbi/decoder.c \
@@ -274,7 +274,7 @@ ccextractor_SOURCES = \
../src/lib_ccx/zvbi/sampling_par.h \
../src/lib_ccx/zvbi/sliced.h \
../src/lib_ccx/zvbi/zvbi_decoder.h \
../src/freetype/* \
../src/freetype/* \
../src/thirdparty/freetype/autofit/autofit.c \
../src/thirdparty/freetype/base/ftbase.c \
../src/thirdparty/freetype/base/ftbbox.c \
@@ -303,7 +303,7 @@ ccextractor_SOURCES = \
../src/thirdparty/freetype/cff/cff.c \
../src/thirdparty/freetype/cid/type1cid.c \
../src/thirdparty/freetype/gzip/ftgzip.c \
../src/thirdparty/freetype/include/ft2build.h \
../src/thirdparty/freetype/include/ft2build.h \
../src/thirdparty/freetype/lzw/ftlzw.c \
../src/thirdparty/freetype/pcf/pcf.c \
../src/thirdparty/freetype/pfr/pfr.c \
@@ -318,20 +318,43 @@ ccextractor_SOURCES = \
../src/thirdparty/freetype/type42/type42.c \
../src/thirdparty/freetype/winfonts/winfnt.c
if SYS_IS_APPLE_SILICON
ccextractor_SOURCES += ../src/thirdparty/libpng/arm/arm_init.c \
../src/thirdparty/libpng/arm/filter_neon_intrinsics.c \
../src/thirdparty/libpng/arm/palette_neon_intrinsics.c
endif
ccextractor_CFLAGS = -std=gnu99 -Wno-write-strings -Wno-pointer-sign -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H
ccextractor_CPPFLAGS =-I../src/lib_ccx/ -I../src/thirdparty/gpacmp4/ -I../src/thirdparty/libpng/ -I../src/thirdparty/zlib/ -I../src/thirdparty/zvbi/ -I../src/thirdparty/lib_hash/ -I../src/thirdparty/protobuf-c/ -I../src/thirdparty -I../src/ -I../src/thirdparty/freetype/include/
ccextractor_CPPFLAGS =-I../src/lib_ccx/ -I../src/thirdparty/gpacmp4/ -I../src/thirdparty/libpng/ -I../src/thirdparty/zlib/ -I../src/lib_ccx/zvbi/ -I../src/thirdparty/lib_hash/ -I../src/thirdparty/protobuf-c/ -I../src/thirdparty -I../src/ -I../src/thirdparty/freetype/include/
ccextractor_LDADD=-lm -lpthread -ldl
if WITH_RUST
ccextractor_LDADD += ./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a
else
ccextractor_CFLAGS += -DDISABLE_RUST
ccextractor_CPPFLAGS += -DDISABLE_RUST
endif
if DEBUG_RELEASE
CARGO_RELEASE_ARGS=
else
CARGO_RELEASE_ARGS=--release
endif
./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a:
cd ../src/rust && \
CARGO_TARGET_DIR=../../linux/rust $(CARGO) build $(CARGO_RELEASE_ARGS);
if SYS_IS_LINUX
ccextractor_CFLAGS += -O3 -s -DGPAC_CONFIG_LINUX
endif
if SYS_IS_MAC
ccextractor_CFLAGS += -DPAC_CONFIG_DARWIN -Dfopen64=fopen -Dopen64=open -Dlseek64=lseek
ccextractor_LDADD += -liconv -lz
ccextractor_LDADD += -liconv -lz
endif
if SYS_IS_64_BIT
@@ -428,7 +451,7 @@ endif
if HARDSUBX_IS_ENABLED
if OCR_IS_ENABLED
ccextractorGUI_CFLAGS += -DENABLE_OCR
ccextractorGUI_CFLAGS += -DENABLE_OCR
endif
endif

View File

@@ -61,6 +61,34 @@ echo "Running pre-build script..."
./pre-build.sh
echo "Trying to compile..."
if [ "$1" = "-without-rust" ]; then
echo "Building without rust files..."
BLD_FLAGS="$BLD_FLAGS -DDISABLE_RUST"
else
BLD_LINKER="$BLD_LINKER ./libccx_rust.a"
echo "Checking for cargo..."
if ! [ -x "$(command -v cargo)" ]; then
echo 'Error: cargo is not installed.' >&2
exit 1
fi
rustc_version="$(rustc --version)"
semver=( ${rustc_version//./ } )
version="${semver[1]}.${semver[2]}.${semver[3]}"
MSRV="1.54.0"
if [ "$(printf '%s\n' "$MSRV" "$version" | sort -V | head -n1)" = "$MSRV" ]; then
echo "rustc >= MSRV(${MSRV})"
else
echo "Minimum supported rust version(MSRV) is ${MSRV}, please upgrade rust"
exit 1
fi
echo "Building rust files..."
(cd ../src/rust && CARGO_TARGET_DIR=../../linux/rust cargo build) || { echo "Failed. " ; exit 1; }
cp rust/debug/libccx_rust.a ./libccx_rust.a
fi
echo "Building ccextractor"
out=$((LC_ALL=C gcc $BLD_FLAGS $BLD_INCLUDE -o ccextractor $BLD_SOURCES $BLD_LINKER)2>&1)
res=$?
if [[ $out == *"gcc: command not found"* ]]

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env sh -ex
#!/usr/bin/env -S sh -ex
####################################################################
# setup by tracey apr 2012
@@ -83,9 +83,6 @@ cd -;
# ccextractor -- build static
git clone https://github.com/CCExtractor/ccextractor;
cd ccextractor/linux/;
# wget https://sourceforge.net/projects/ccextractor/files/ccextractor/0.82/ccextractor.src.0.82.zip;
# unzip ccextractor*.zip;
# cd ccextractor.*/linux/;
perl -i -pe 's/O3 /O3 -static /' Makefile;
# quick patch:
perl -i -pe 's/(strchr|strstr)\(/$1((char *)/' ../src/thirdparty/gpacmp4/url.c ../src/thirdparty/gpacmp4/error.c;

View File

@@ -2,11 +2,11 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([CCExtractor], [0.89], [carlos@ccextractor.org])
AC_INIT([CCExtractor], [0.94], [carlos@ccextractor.org])
AC_CONFIG_AUX_DIR([build-conf])
AC_CONFIG_SRCDIR([../src/ccextractor.c])
AM_INIT_AUTOMAKE([foreign subdir-objects])
AC_CONFIG_MACRO_DIRS([m4])
# Checks for programs.
AC_PROG_CC
@@ -91,6 +91,50 @@ AC_HELP_STRING([--with-gui], [Builds CCExtractor with GUI (requires GLFW and GLE
[PKG_CHECK_MODULES([glfw3], [glfw3]) && PKG_CHECK_MODULES([glew], [glew])],
[with_gui=no])
#Add argument for rust
AC_ARG_WITH([rust],
AC_HELP_STRING([--with-rust], [Builds CCExtractor with rust library]),
[with_rust=$withval],
[with_rust=yes])
AC_MSG_CHECKING(whether to build with rust library)
if test "x$with_rust" = "xyes" ; then
AC_MSG_RESULT(yes)
#Check if cargo and rust is installed
AC_PATH_PROG([CARGO], [cargo], [notfound])
AS_IF([test "$CARGO" = "notfound"], [AC_MSG_ERROR([cargo is required])])
AC_PATH_PROG([RUSTC], [rustc], [notfound])
AS_IF([test "$RUSTC" = "notfound"], [AC_MSG_ERROR([rustc is required])])
rustc_version=$(rustc --version)
MSRV="1.54.0"
AX_COMPARE_VERSION($rustc_version, [ge], [$MSRV],
[AC_MSG_RESULT(rustc >= $MSRV)],
[AC_MSG_ERROR([Minimum supported rust version(MSRV) is $MSRV, please upgrade rust])])
else
AC_MSG_RESULT(no)
fi
AM_CONDITIONAL([WITH_RUST], [test "x$with_rust" = "xyes"])
AC_ARG_ENABLE(debug,
AC_HELP_STRING([--enable-debug],
[Build Rust code with debugging information [default=no]]),
[debug_release=$enableval],
[debug_release=no])
AC_MSG_CHECKING(whether to build Rust code with debugging information)
if test "x$debug_release" = "xyes" ; then
AC_MSG_RESULT(yes)
RUST_TARGET_SUBDIR=debug
else
AC_MSG_RESULT(no)
RUST_TARGET_SUBDIR=release
fi
AM_CONDITIONAL([DEBUG_RELEASE], [test "x$debug_release" = "xyes"])
AC_SUBST([RUST_TARGET_SUBDIR])
#Checks and prompts if libraries found/not found to avoild failure while building
AS_IF([ test x$hardsubx = xtrue && test $HAS_AVCODEC -gt 0 ], [AC_MSG_NOTICE(avcodec library found)])
@@ -114,6 +158,7 @@ AM_CONDITIONAL(TESSERACT_PRESENT, [ test ! -z `pkg-config --libs-only-l --silen
AM_CONDITIONAL(TESSERACT_PRESENT_RPI, [ test -d "/usr/include/tesseract" && test `ls -A /usr/include/tesseract | wc -l` -gt 0 ])
AM_CONDITIONAL(SYS_IS_LINUX, [ test `uname -s` = "Linux"])
AM_CONDITIONAL(SYS_IS_MAC, [ test `uname -s` = "Darwin"])
AM_CONDITIONAL(SYS_IS_APPLE_SILICON, [ test `uname -a | awk '{print $NF}'` = "arm64" ])
AM_CONDITIONAL(BUILD_WITH_GUI, [test "x$with_gui" = "xyes"])
AM_CONDITIONAL(SYS_IS_64_BIT,[test `getconf LONG_BIT` = "64"])

View File

@@ -0,0 +1,177 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_compare_version.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
#
# DESCRIPTION
#
# This macro compares two version strings. Due to the various number of
# minor-version numbers that can exist, and the fact that string
# comparisons are not compatible with numeric comparisons, this is not
# necessarily trivial to do in a autoconf script. This macro makes doing
# these comparisons easy.
#
# The six basic comparisons are available, as well as checking equality
# limited to a certain number of minor-version levels.
#
# The operator OP determines what type of comparison to do, and can be one
# of:
#
# eq - equal (test A == B)
# ne - not equal (test A != B)
# le - less than or equal (test A <= B)
# ge - greater than or equal (test A >= B)
# lt - less than (test A < B)
# gt - greater than (test A > B)
#
# Additionally, the eq and ne operator can have a number after it to limit
# the test to that number of minor versions.
#
# eq0 - equal up to the length of the shorter version
# ne0 - not equal up to the length of the shorter version
# eqN - equal up to N sub-version levels
# neN - not equal up to N sub-version levels
#
# When the condition is true, shell commands ACTION-IF-TRUE are run,
# otherwise shell commands ACTION-IF-FALSE are run. The environment
# variable 'ax_compare_version' is always set to either 'true' or 'false'
# as well.
#
# Examples:
#
# AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8])
# AX_COMPARE_VERSION([3.15],[lt],[3.15.8])
#
# would both be true.
#
# AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8])
# AX_COMPARE_VERSION([3.15],[gt],[3.15.8])
#
# would both be false.
#
# AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8])
#
# would be true because it is only comparing two minor versions.
#
# AX_COMPARE_VERSION([3.15.7],[eq0],[3.15])
#
# would be true because it is only comparing the lesser number of minor
# versions of the two values.
#
# Note: The characters that separate the version numbers do not matter. An
# empty string is the same as version 0. OP is evaluated by autoconf, not
# configure, so must be a string, not a variable.
#
# The author would like to acknowledge Guido Draheim whose advice about
# the m4_case and m4_ifvaln functions make this macro only include the
# portions necessary to perform the specific comparison specified by the
# OP argument in the final configure script.
#
# LICENSE
#
# Copyright (c) 2008 Tim Toolan <toolan@ele.uri.edu>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 13
dnl #########################################################################
AC_DEFUN([AX_COMPARE_VERSION], [
AC_REQUIRE([AC_PROG_AWK])
# Used to indicate true or false condition
ax_compare_version=false
# Convert the two version strings to be compared into a format that
# allows a simple string comparison. The end result is that a version
# string of the form 1.12.5-r617 will be converted to the form
# 0001001200050617. In other words, each number is zero padded to four
# digits, and non digits are removed.
AS_VAR_PUSHDEF([A],[ax_compare_version_A])
A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
-e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
-e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
-e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
-e 's/[[^0-9]]//g'`
AS_VAR_PUSHDEF([B],[ax_compare_version_B])
B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
-e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
-e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
-e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
-e 's/[[^0-9]]//g'`
dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary
dnl # then the first line is used to determine if the condition is true.
dnl # The sed right after the echo is to remove any indented white space.
m4_case(m4_tolower($2),
[lt],[
ax_compare_version=`echo "x$A
x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"`
],
[gt],[
ax_compare_version=`echo "x$A
x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"`
],
[le],[
ax_compare_version=`echo "x$A
x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"`
],
[ge],[
ax_compare_version=`echo "x$A
x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"`
],[
dnl Split the operator from the subversion count if present.
m4_bmatch(m4_substr($2,2),
[0],[
# A count of zero means use the length of the shorter version.
# Determine the number of characters in A and B.
ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'`
ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'`
# Set A to no more than B's length and B to no more than A's length.
A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"`
B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"`
],
[[0-9]+],[
# A count greater than zero means use only that many subversions
A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
],
[.+],[
AC_WARNING(
[invalid OP numeric parameter: $2])
],[])
# Pad zeros at end of numbers to make same length.
ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`"
B="$B`echo $A | sed 's/./0/g'`"
A="$ax_compare_version_tmp_A"
# Check for equality or inequality as necessary.
m4_case(m4_tolower(m4_substr($2,0,2)),
[eq],[
test "x$A" = "x$B" && ax_compare_version=true
],
[ne],[
test "x$A" != "x$B" && ax_compare_version=true
],[
AC_WARNING([invalid OP parameter: $2])
])
])
AS_VAR_POPDEF([A])dnl
AS_VAR_POPDEF([B])dnl
dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE.
if test "$ax_compare_version" = "true" ; then
m4_ifvaln([$4],[$4],[:])dnl
m4_ifvaln([$5],[else $5])dnl
fi
]) dnl AX_COMPARE_VERSION

View File

@@ -1,5 +1,5 @@
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4/
bin_PROGRAMS = ccextractor
ccextractor_SOURCES = \
@@ -80,6 +80,7 @@ ccextractor_SOURCES = \
../src/thirdparty/gpacmp4/gpac/tools.h \
../src/thirdparty/gpacmp4/gpac/utf.h \
../src/thirdparty/gpacmp4/gpac/version.h \
../src/thirdparty/gpacmp4/gpac/iso639.h \
../src/thirdparty/gpacmp4/gpac/internal/avilib.h \
../src/thirdparty/gpacmp4/gpac/internal/isomedia_dev.h \
../src/thirdparty/gpacmp4/gpac/internal/media_dev.h \
@@ -261,18 +262,19 @@ ccextractor_SOURCES = \
../src/thirdparty/lib_hash/sha2.h \
../src/thirdparty/protobuf-c/protobuf-c.c \
../src/thirdparty/protobuf-c/protobuf-c.h \
../src/thirdparty/zvbi/bcd.h \
../src/thirdparty/zvbi/bit_slicer.c \
../src/thirdparty/zvbi/bit_slicer.h \
../src/thirdparty/zvbi/decoder.c \
../src/thirdparty/zvbi/macros.h \
../src/thirdparty/zvbi/misc.h \
../src/thirdparty/zvbi/raw_decoder.c \
../src/thirdparty/zvbi/raw_decoder.h \
../src/thirdparty/zvbi/sampling_par.c \
../src/thirdparty/zvbi/sampling_par.h \
../src/thirdparty/zvbi/sliced.h \
../src/thirdparty/zvbi/zvbi_decoder.h \
../src/lib_ccx/zvbi/bcd.h \
../src/lib_ccx/zvbi/bit_slicer.c \
../src/lib_ccx/zvbi/bit_slicer.h \
../src/lib_ccx/zvbi/decoder.c \
../src/lib_ccx/zvbi/macros.h \
../src/lib_ccx/zvbi/misc.h \
../src/lib_ccx/zvbi/raw_decoder.c \
../src/lib_ccx/zvbi/raw_decoder.h \
../src/lib_ccx/zvbi/sampling_par.c \
../src/lib_ccx/zvbi/sampling_par.h \
../src/lib_ccx/zvbi/sliced.h \
../src/lib_ccx/zvbi/zvbi_decoder.h \
../src/freetype/* \
../src/thirdparty/freetype/autofit/autofit.c \
../src/thirdparty/freetype/base/ftbase.c \
../src/thirdparty/freetype/base/ftbbox.c \
@@ -301,6 +303,7 @@ ccextractor_SOURCES = \
../src/thirdparty/freetype/cff/cff.c \
../src/thirdparty/freetype/cid/type1cid.c \
../src/thirdparty/freetype/gzip/ftgzip.c \
../src/thirdparty/freetype/include/ft2build.h \
../src/thirdparty/freetype/lzw/ftlzw.c \
../src/thirdparty/freetype/pcf/pcf.c \
../src/thirdparty/freetype/pfr/pfr.c \
@@ -314,22 +317,48 @@ ccextractor_SOURCES = \
../src/thirdparty/freetype/type1/type1.c \
../src/thirdparty/freetype/type42/type42.c \
../src/thirdparty/freetype/winfonts/winfnt.c
if SYS_IS_APPLE_SILICON
ccextractor_SOURCES += ../src/thirdparty/libpng/arm/arm_init.c \
../src/thirdparty/libpng/arm/filter_neon_intrinsics.c \
../src/thirdparty/libpng/arm/palette_neon_intrinsics.c
endif
ccextractor_CFLAGS = -std=gnu99 -Wno-write-strings -Wno-pointer-sign -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H
ccextractor_CPPFLAGS =-I../src/lib_ccx/ -I../src/thirdparty/gpacmp4/ -I../src/thirdparty/libpng/ -I../src/thirdparty/zlib/ -I../src/thirdparty/zvbi/ -I../src/thirdparty/lib_hash/ -I../src/thirdparty/protobuf-c -I../src/thirdparty -I../src -I../src/thirdparty/freetype/include
ccextractor_CPPFLAGS =-I../src/lib_ccx/ -I../src/thirdparty/gpacmp4/ -I../src/thirdparty/libpng/ -I../src/thirdparty/zlib/ -I../src/lib_ccx/zvbi/ -I../src/thirdparty/lib_hash/ -I../src/thirdparty/protobuf-c/ -I../src/thirdparty -I../src/ -I../src/thirdparty/freetype/include/
ccextractor_LDADD=-lm -lpthread -ldl
if WITH_RUST
ccextractor_LDADD += ./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a
else
ccextractor_CFLAGS += -DDISABLE_RUST
ccextractor_CPPFLAGS += -DDISABLE_RUST
endif
if DEBUG_RELEASE
CARGO_RELEASE_ARGS=
else
CARGO_RELEASE_ARGS=--release
endif
./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a:
cd ../src/rust && \
CARGO_TARGET_DIR=../../linux/rust $(CARGO) build $(CARGO_RELEASE_ARGS);
if SYS_IS_LINUX
ccextractor_CFLAGS += -O3 -s -DGPAC_CONFIG_LINUX
endif
if SYS_IS_MAC
ccextractor_CFLAGS += -DPAC_CONFIG_DARWIN -Dfopen64=fopen -Dopen64=open -Dlseek64=lseek
ccextractor_LDADD += -liconv -lz
ccextractor_LDADD += -liconv -lz
endif
if SYS_IS_64_BIT
ccextractor_CFLAGS += -DGPAC_64_BITS
endif
if HARDSUBX_IS_ENABLED
@@ -417,12 +446,12 @@ ccextractorGUI_CFLAGS += -O3 -DUNIX
ccextractorGUI_CFLAGS += ${glew_CFLAGS}
ccextractorGUI_LDADD += ${glew_LIBS}
ccextractorGUI_LDFLAGS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo
ccextractorGUI_LDADD += -lm -L/usr/local/lib -lpthread
ccextractorGUI_LDADD += -lglfw -lm -L/usr/local/lib -lpthread
endif
if HARDSUBX_IS_ENABLED
if OCR_IS_ENABLED
ccextractorGUI_CFLAGS += -DENABLE_OCR
ccextractorGUI_CFLAGS += -DENABLE_OCR
endif
endif

View File

@@ -1,8 +1,8 @@
#!/bin/bash
cd `dirname $0`
BLD_FLAGS="-std=gnu99 -Wno-write-strings -Wno-pointer-sign -DGPAC_CONFIG_DARWIN -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -Dfopen64=fopen -Dopen64=open -Dlseek64=lseek -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H"
BLD_FLAGS="-std=gnu99 -Wno-write-strings -Wno-pointer-sign -DGPAC_CONFIG_DARWIN -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -Dfopen64=fopen -Dopen64=open -Dlseek64=lseek -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H -DDISABLE_RUST"
[[ $1 = "OCR" ]] && BLD_FLAGS="$BLD_FLAGS -DENABLE_OCR"
BLD_INCLUDE="-I../src/ -I../src/lib_ccx -I../src/thirdparty/gpacmp4 -I../src/lib_hash -I../src/thirdparty/libpng -I../src/thirdparty -I../src/thirdparty/protobuf-c -I../src/thirdparty/zlib -I../src/thirdparty/zvbi -I../src/thirdparty/freetype/include"
BLD_INCLUDE="-I../src/ -I../src/lib_ccx -I../src/thirdparty/gpacmp4 -I../src/lib_hash -I../src/thirdparty/libpng -I../src/thirdparty -I../src/thirdparty/protobuf-c -I../src/thirdparty/zlib -I../src/thirdparty/freetype/include"
[[ $1 = "OCR" ]] && BLD_INCLUDE="$BLD_INCLUDE `pkg-config --cflags --silence-errors tesseract`"
SRC_CCX="$(find ../src/lib_ccx -name '*.c')"
SRC_GPAC="$(find ../src/thirdparty/gpacmp4 -name '*.c')"
@@ -11,7 +11,6 @@ SRC_LIBPNG="$(find ../src/thirdparty/libpng -name '*.c')"
SRC_PROTOBUF="$(find ../src/thirdparty/protobuf-c -name '*.c')"
SRC_UTF8="../src/thirdparty/utf8proc/utf8proc.c"
SRC_ZLIB="$(find ../src/thirdparty/zlib -name '*.c')"
SRC_ZVBI="$(find ../src/thirdparty/zvbi -name '*.c')"
SRC_FREETYPE="../src/thirdparty/freetype/autofit/autofit.c \
../src/thirdparty/freetype/base/ftbase.c \
../src/thirdparty/freetype/base/ftbbox.c \

View File

@@ -1,12 +1,12 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([CCExtractor], [0.89], [carlos@ccextractor.org])
AC_PREREQ([2.71])
AC_INIT([CCExtractor],[0.94],[carlos@ccextractor.org])
AC_CONFIG_AUX_DIR([build-conf])
AC_CONFIG_SRCDIR([../src/ccextractor.c])
AM_INIT_AUTOMAKE([foreign subdir-objects])
AC_CONFIG_MACRO_DIRS([m4])
# Checks for programs.
AC_PROG_CC
@@ -63,7 +63,7 @@ AC_CHECK_FUNCS([floor ftruncate gethostbyname gettimeofday inet_ntoa mblen memch
# Checks for arguments with configure
AC_ARG_ENABLE([hardsubx],
AC_HELP_STRING([--enable-hardsubx], [Enables extraction of burnt subtitles (hard subtitles)]),
AS_HELP_STRING([--enable-hardsubx],[Enables extraction of burnt subtitles (hard subtitles)]),
[case "${enableval}" in
yes) hardsubx=true ;;
no) hardsubx=false ;;
@@ -71,7 +71,7 @@ AC_HELP_STRING([--enable-hardsubx], [Enables extraction of burnt subtitles (hard
esac],[hardsubx=false])
AC_ARG_ENABLE([ocr],
AC_HELP_STRING([--enable-ocr], [Enables Optical Character Recognition]),
AS_HELP_STRING([--enable-ocr],[Enables Optical Character Recognition]),
[case "${enableval}" in
yes) ocr=true ;;
no) ocr=false ;;
@@ -79,7 +79,7 @@ AC_HELP_STRING([--enable-ocr], [Enables Optical Character Recognition]),
esac],[ocr=false])
AC_ARG_ENABLE([ffmpeg],
AC_HELP_STRING([--enable-ffmpeg], [Enable FFmpeg integration]),
AS_HELP_STRING([--enable-ffmpeg],[Enable FFmpeg integration]),
[case "${enableval}" in
yes) ffmpeg=true ;;
no) ffmpeg=false ;;
@@ -87,12 +87,55 @@ AC_HELP_STRING([--enable-ffmpeg], [Enable FFmpeg integration]),
esac],[ffmpeg=false])
AC_ARG_WITH([gui],
AC_HELP_STRING([--with-gui], [Builds CCExtractor with GUI (requires GLFW and GLEW)]),
AS_HELP_STRING([--with-gui],[Builds CCExtractor with GUI (requires GLFW and GLEW)]),
[PKG_CHECK_MODULES([glfw3], [glfw3]) && PKG_CHECK_MODULES([glew], [glew])],
[with_gui=no])
#Add argument for rust
AC_ARG_WITH([rust],
AS_HELP_STRING([--with-rust],[Builds CCExtractor with rust library]),
[with_rust=$withval],
[with_rust=yes])
#Checks and prompts if libraries found/not found to avoild failure while building
AC_MSG_CHECKING(whether to build with rust library)
if test "x$with_rust" = "xyes" ; then
AC_MSG_RESULT(yes)
#Check if cargo and rust is installed
AC_PATH_PROG([CARGO], [cargo], [notfound])
AS_IF([test "$CARGO" = "notfound"], [AC_MSG_ERROR([cargo is required])])
AC_PATH_PROG([RUSTC], [rustc], [notfound])
AS_IF([test "$RUSTC" = "notfound"], [AC_MSG_ERROR([rustc is required])])
rustc_version=$(rustc --version)
MSRV="1.54.0"
AX_COMPARE_VERSION($rustc_version, [ge], [$MSRV],
[AC_MSG_RESULT(rustc >= $MSRV)],
[AC_MSG_ERROR([Minimum supported rust version(MSRV) is $MSRV, please upgrade rust])])
else
AC_MSG_RESULT(no)
fi
AM_CONDITIONAL([WITH_RUST], [test "x$with_rust" = "xyes"])
AC_ARG_ENABLE(debug,
AS_HELP_STRING([--enable-debug],[Build Rust code with debugging information [default=no]]),
[debug_release=$enableval],
[debug_release=no])
AC_MSG_CHECKING(whether to build Rust code with debugging information)
if test "x$debug_release" = "xyes" ; then
AC_MSG_RESULT(yes)
RUST_TARGET_SUBDIR=debug
else
AC_MSG_RESULT(no)
RUST_TARGET_SUBDIR=release
fi
AM_CONDITIONAL([DEBUG_RELEASE], [test "x$debug_release" = "xyes"])
AC_SUBST([RUST_TARGET_SUBDIR])
#Checks and prompts if libraries found/not found to avoid failure while building
AS_IF([ test x$hardsubx = xtrue && test $HAS_AVCODEC -gt 0 ], [AC_MSG_NOTICE(avcodec library found)])
AS_IF([ test x$hardsubx = xtrue && test ! $HAS_AVCODEC -gt 0 ], [AC_MSG_ERROR(avcodec library not found. Please install the avcodec library before proceeding)])
AS_IF([ test x$hardsubx = xtrue && test $HAS_AVFORMAT -gt 0 ], [AC_MSG_NOTICE(avformat library found)])
@@ -110,11 +153,13 @@ AS_IF([ (test x$ocr = xtrue || test x$hardsubx = xtrue) && test ! $HAS_LEPT -gt
AM_CONDITIONAL(HARDSUBX_IS_ENABLED, [ test x$hardsubx = xtrue ])
AM_CONDITIONAL(OCR_IS_ENABLED, [ test x$ocr = xtrue || test x$hardsubx = xtrue ])
AM_CONDITIONAL(FFMPEG_IS_ENABLED, [ test x$ffmpeg = xtrue ])
AM_CONDITIONAL(TESSERACT_PRESENT, [ test ! -z `pkg-config --libs-only-l --silence-errors tesseract`])
AM_CONDITIONAL(TESSERACT_PRESENT, [ test ! -z `pkg-config --libs-only-l --silence-errors tesseract` ])
AM_CONDITIONAL(TESSERACT_PRESENT_RPI, [ test -d "/usr/include/tesseract" && test `ls -A /usr/include/tesseract | wc -l` -gt 0 ])
AM_CONDITIONAL(SYS_IS_LINUX, [ test `uname -s` = "Linux"])
AM_CONDITIONAL(SYS_IS_MAC, [ test `uname -s` = "Darwin"])
AM_CONDITIONAL(SYS_IS_APPLE_SILICON, [ test `uname -a | awk '{print $NF}'` = "arm64" ])
AM_CONDITIONAL(BUILD_WITH_GUI, [test "x$with_gui" = "xyes"])
AM_CONDITIONAL(SYS_IS_64_BIT,[test `getconf LONG_BIT` = "64"])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

View File

@@ -0,0 +1,177 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_compare_version.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
#
# DESCRIPTION
#
# This macro compares two version strings. Due to the various number of
# minor-version numbers that can exist, and the fact that string
# comparisons are not compatible with numeric comparisons, this is not
# necessarily trivial to do in a autoconf script. This macro makes doing
# these comparisons easy.
#
# The six basic comparisons are available, as well as checking equality
# limited to a certain number of minor-version levels.
#
# The operator OP determines what type of comparison to do, and can be one
# of:
#
# eq - equal (test A == B)
# ne - not equal (test A != B)
# le - less than or equal (test A <= B)
# ge - greater than or equal (test A >= B)
# lt - less than (test A < B)
# gt - greater than (test A > B)
#
# Additionally, the eq and ne operator can have a number after it to limit
# the test to that number of minor versions.
#
# eq0 - equal up to the length of the shorter version
# ne0 - not equal up to the length of the shorter version
# eqN - equal up to N sub-version levels
# neN - not equal up to N sub-version levels
#
# When the condition is true, shell commands ACTION-IF-TRUE are run,
# otherwise shell commands ACTION-IF-FALSE are run. The environment
# variable 'ax_compare_version' is always set to either 'true' or 'false'
# as well.
#
# Examples:
#
# AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8])
# AX_COMPARE_VERSION([3.15],[lt],[3.15.8])
#
# would both be true.
#
# AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8])
# AX_COMPARE_VERSION([3.15],[gt],[3.15.8])
#
# would both be false.
#
# AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8])
#
# would be true because it is only comparing two minor versions.
#
# AX_COMPARE_VERSION([3.15.7],[eq0],[3.15])
#
# would be true because it is only comparing the lesser number of minor
# versions of the two values.
#
# Note: The characters that separate the version numbers do not matter. An
# empty string is the same as version 0. OP is evaluated by autoconf, not
# configure, so must be a string, not a variable.
#
# The author would like to acknowledge Guido Draheim whose advice about
# the m4_case and m4_ifvaln functions make this macro only include the
# portions necessary to perform the specific comparison specified by the
# OP argument in the final configure script.
#
# LICENSE
#
# Copyright (c) 2008 Tim Toolan <toolan@ele.uri.edu>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 13
dnl #########################################################################
AC_DEFUN([AX_COMPARE_VERSION], [
AC_REQUIRE([AC_PROG_AWK])
# Used to indicate true or false condition
ax_compare_version=false
# Convert the two version strings to be compared into a format that
# allows a simple string comparison. The end result is that a version
# string of the form 1.12.5-r617 will be converted to the form
# 0001001200050617. In other words, each number is zero padded to four
# digits, and non digits are removed.
AS_VAR_PUSHDEF([A],[ax_compare_version_A])
A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
-e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
-e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
-e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
-e 's/[[^0-9]]//g'`
AS_VAR_PUSHDEF([B],[ax_compare_version_B])
B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
-e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
-e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
-e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
-e 's/[[^0-9]]//g'`
dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary
dnl # then the first line is used to determine if the condition is true.
dnl # The sed right after the echo is to remove any indented white space.
m4_case(m4_tolower($2),
[lt],[
ax_compare_version=`echo "x$A
x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"`
],
[gt],[
ax_compare_version=`echo "x$A
x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"`
],
[le],[
ax_compare_version=`echo "x$A
x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"`
],
[ge],[
ax_compare_version=`echo "x$A
x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"`
],[
dnl Split the operator from the subversion count if present.
m4_bmatch(m4_substr($2,2),
[0],[
# A count of zero means use the length of the shorter version.
# Determine the number of characters in A and B.
ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'`
ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'`
# Set A to no more than B's length and B to no more than A's length.
A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"`
B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"`
],
[[0-9]+],[
# A count greater than zero means use only that many subversions
A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
],
[.+],[
AC_WARNING(
[invalid OP numeric parameter: $2])
],[])
# Pad zeros at end of numbers to make same length.
ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`"
B="$B`echo $A | sed 's/./0/g'`"
A="$ax_compare_version_tmp_A"
# Check for equality or inequality as necessary.
m4_case(m4_tolower(m4_substr($2,0,2)),
[eq],[
test "x$A" = "x$B" && ax_compare_version=true
],
[ne],[
test "x$A" != "x$B" && ax_compare_version=true
],[
AC_WARNING([invalid OP parameter: $2])
])
])
AS_VAR_POPDEF([A])dnl
AS_VAR_POPDEF([B])dnl
dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE.
if test "$ax_compare_version" = "true" ; then
m4_ifvaln([$4],[$4],[:])dnl
m4_ifvaln([$5],[else $5])dnl
fi
]) dnl AX_COMPARE_VERSION

View File

@@ -1,5 +1,5 @@
pkgname=ccextractor
pkgver=0.89
pkgver=0.94
pkgrel=1
pkgdesc="A closed captions and teletext subtitles extractor for video streams."
arch=('i686' 'x86_64')

View File

@@ -6,6 +6,7 @@ option (WITH_FFMPEG "Build using FFmpeg demuxer and decoder" OFF)
option (WITH_OCR "Build with OCR (Optical Character Recognition) feature" OFF)
option (WITH_SHARING "Build with sharing and translation support" OFF)
option (WITH_HARDSUBX "Build with support for burned-in subtitles" OFF)
option (WITHOUT_RUST "Build without Rust library" OFF)
# Version number
set (CCEXTRACTOR_VERSION_MAJOR 0)
@@ -42,6 +43,14 @@ configure_file (
add_definitions(-DVERSION_FILE_PRESENT -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H)
if(UNIX)
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
add_definitions(-DGPAC_CONFIG_DARWIN)
else ()
add_definitions(-DGPAC_CONFIG_LINUX)
endif()
endif(UNIX)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
add_definitions(-DGPAC_64_BITS)
endif()
@@ -54,6 +63,12 @@ include_directories(${PROJECT_SOURCE_DIR}/thirdparty/gpacmp4)
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/protobuf-c)
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/lib_hash)
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/libpng)
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND ${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "arm64")
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/libpng/arm)
aux_source_directory(${PROJECT_SOURCE_DIR}/thirdparty/libpng/arm SOURCEFILE)
endif ()
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/zlib)
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/freetype/include)
aux_source_directory(${PROJECT_SOURCE_DIR}/thirdparty/gpacmp4/ SOURCEFILE)
@@ -226,6 +241,21 @@ if (PKG_CONFIG_FOUND AND WITH_HARDSUBX)
endif (PKG_CONFIG_FOUND AND WITH_HARDSUBX)
add_executable (ccextractor ${SOURCEFILE} ${FREETYPE_SOURCE} ${UTF8PROC_SOURCE})
########################################################
# Build with Rust library
########################################################
if (PKG_CONFIG_FOUND AND NOT WITHOUT_RUST)
add_subdirectory (rust)
get_target_property(RUST_LIB ccx_rust LOCATION)
set (EXTRA_LIBS ${EXTRA_LIBS} ${RUST_LIB})
add_dependencies(ccextractor ccx_rust)
else ()
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDISABLE_RUST")
endif (PKG_CONFIG_FOUND AND NOT WITHOUT_RUST)
target_link_libraries (ccextractor ${EXTRA_LIBS})
target_include_directories (ccextractor PUBLIC ${EXTRA_INCLUDES})

View File

@@ -86,6 +86,10 @@ if (MINGW OR CYGWIN)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGPAC_CONFIG_WIN32")
endif (MINGW OR CYGWIN)
if (WITHOUT_RUST)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDISABLE_RUST")
endif (WITHOUT_RUST)
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGPAC_CONFIG_LINUX")
endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")

View File

@@ -22,6 +22,8 @@ void init_options(struct ccx_s_options *options)
options->settings_608.force_rollup = 0;
options->settings_608.screens_to_process = -1;
options->settings_608.default_color = COL_TRANSPARENT; // Defaults to transparent/no-color.
options->is_608_enabled = 0;
options->is_708_enabled = 0;
options->extract = 1; // Extract 1st field only (primary language)
options->cc_channel = 1; // Channel we want to dump in srt mode
@@ -131,15 +133,12 @@ void init_options(struct ccx_s_options *options)
options->enc_cfg.start_credits_text = NULL;
options->enc_cfg.end_credits_text = NULL;
options->enc_cfg.encoding = CCX_ENC_UTF_8;
#ifdef _WIN32
options->enc_cfg.no_bom = 0; // Use BOM by default for windows only
#else
options->enc_cfg.no_bom = 1;
#endif
options->enc_cfg.services_charsets = NULL;
options->enc_cfg.all_services_charset = NULL;
options->enc_cfg.with_semaphore = 0;
options->enc_cfg.force_dropframe = 0; // Assume No Drop Frame for MCC Encode.
options->enc_cfg.extract_only_708 = 0;
options->settings_dtvcc.enabled = 0;
options->settings_dtvcc.active_services_count = 0;

View File

@@ -84,6 +84,7 @@ struct encoder_cfg
int services_enabled[CCX_DTVCC_MAX_SERVICES];
char** services_charsets;
char* all_services_charset;
int extract_only_708; // 1 if only 708 subs extraction is enabled
};
struct ccx_s_options // Options from user parameters
@@ -102,6 +103,8 @@ struct ccx_s_options // Options from user parameters
ccx_decoder_608_settings settings_608; // Contains the settings for the 608 decoder.
ccx_decoder_dtvcc_settings settings_dtvcc; // Same for 708 decoder
int is_608_enabled; // Is 608 enabled by explicitly using flags(-1,-2,-12)
int is_708_enabled; // Is 708 enabled by explicitly using flags(-svc)
char millis_separator;
int binary_concat; // Disabled by -ve or --videoedited

View File

@@ -1,119 +1,119 @@
#ifndef CCX_PLATFORM_H
#define CCX_PLATFORM_H
// Default includes (cross-platform)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <fcntl.h>
#include <stdarg.h>
#include <errno.h>
#define __STDC_FORMAT_MACROS
#ifdef _WIN32
#define inline _inline
#define typeof decltype
#include <io.h>
#include <ws2tcpip.h>
#include <windows.h>
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#include "inttypes.h"
#define UINT64_MAX _UI64_MAX
typedef int socklen_t;
typedef int ssize_t;
typedef uint32_t in_addr_t;
#ifndef IN_CLASSD
#define IN_CLASSD(i) (((INT32)(i) & 0xf0000000) == 0xe0000000)
#define IN_MULTICAST(i) IN_CLASSD(i)
#endif
#include <direct.h>
#define mkdir(path, mode) _mkdir(path)
#ifndef snprintf
// Added ifndef because VS2013 warns for macro redefinition.
#define snprintf(buf, len, fmt, ...) _snprintf(buf, len, fmt, __VA_ARGS__)
#endif
#define sleep(sec) Sleep((sec) * 1000)
#include <fcntl.h>
#else // _WIN32
#include <unistd.h>
#define __STDC_LIMIT_MACROS
#include <inttypes.h>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/stat.h>
#include <sys/types.h>
#endif // _WIN32
#include "disable_warnings.h"
#ifdef _MSC_VER
#include "stdintmsc.h"
// Don't bug me with strcpy() deprecation warnings
#pragma warning(disable : 4996)
#else
#include <stdint.h>
#endif
#ifdef __OpenBSD__
#define FOPEN64 fopen
#define OPEN open
#define FSEEK fseek
#define FTELL ftell
#define LSEEK lseek
#define FSTAT fstat
#else
#ifdef _WIN32
#define OPEN _open
// 64 bit file functions
#if defined(_MSC_VER)
#define FSEEK _fseeki64
#define FTELL _ftelli64
#else
// For MinGW
#define FSEEK fseeko64
#define FTELL ftello64
#endif
#define TELL _telli64
#define LSEEK _lseeki64
typedef struct _stati64 FSTATSTRUCT;
#else
// Linux internally maps these functions to 64bit usage,
// if _FILE_OFFSET_BITS macro is set to 64
#define FOPEN64 fopen
#define OPEN open
#define LSEEK lseek
#define FSEEK fseek
#define FTELL ftell
#define FSTAT fstat
#define TELL tell
#include <stdint.h>
#endif
#endif
#ifndef int64_t_C
#define int64_t_C(c) (c ## LL)
#define uint64_t_C(c) (c ## ULL)
#endif
#ifndef O_BINARY
#define O_BINARY 0 // Not present in Linux because it's always binary
#endif
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
typedef int64_t LLONG;
typedef uint64_t ULLONG;
typedef uint8_t UBYTE;
#endif // CCX_PLATFORM_H
#ifndef CCX_PLATFORM_H
#define CCX_PLATFORM_H
// Default includes (cross-platform)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <fcntl.h>
#include <stdarg.h>
#include <errno.h>
#define __STDC_FORMAT_MACROS
#ifdef _WIN32
#define inline _inline
#define typeof decltype
#include <io.h>
#include <ws2tcpip.h>
#include <windows.h>
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#include "inttypes.h"
#define UINT64_MAX _UI64_MAX
typedef int socklen_t;
typedef int ssize_t;
typedef uint32_t in_addr_t;
#ifndef IN_CLASSD
#define IN_CLASSD(i) (((INT32)(i) & 0xf0000000) == 0xe0000000)
#define IN_MULTICAST(i) IN_CLASSD(i)
#endif
#include <direct.h>
#define mkdir(path, mode) _mkdir(path)
#ifndef snprintf
// Added ifndef because VS2013 warns for macro redefinition.
#define snprintf(buf, len, fmt, ...) _snprintf(buf, len, fmt, __VA_ARGS__)
#endif
#define sleep(sec) Sleep((sec) * 1000)
#include <fcntl.h>
#else // _WIN32
#include <unistd.h>
#define __STDC_LIMIT_MACROS
#include <inttypes.h>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/stat.h>
#include <sys/types.h>
#endif // _WIN32
//#include "disable_warnings.h"
#if defined(_MSC_VER) && !defined(__clang__)
#include "stdintmsc.h"
// Don't bug me with strcpy() deprecation warnings
#pragma warning(disable : 4996)
#else
#include <stdint.h>
#endif
#ifdef __OpenBSD__
#define FOPEN64 fopen
#define OPEN open
#define FSEEK fseek
#define FTELL ftell
#define LSEEK lseek
#define FSTAT fstat
#else
#ifdef _WIN32
#define OPEN _open
// 64 bit file functions
#if defined(_MSC_VER)
#define FSEEK _fseeki64
#define FTELL _ftelli64
#else
// For MinGW
#define FSEEK fseeko64
#define FTELL ftello64
#endif
#define TELL _telli64
#define LSEEK _lseeki64
typedef struct _stati64 FSTATSTRUCT;
#else
// Linux internally maps these functions to 64bit usage,
// if _FILE_OFFSET_BITS macro is set to 64
#define FOPEN64 fopen
#define OPEN open
#define LSEEK lseek
#define FSEEK fseek
#define FTELL ftell
#define FSTAT fstat
#define TELL tell
#include <stdint.h>
#endif
#endif
#ifndef int64_t_C
#define int64_t_C(c) (c ## LL)
#define uint64_t_C(c) (c ## ULL)
#endif
#ifndef O_BINARY
#define O_BINARY 0 // Not present in Linux because it's always binary
#endif
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
typedef int64_t LLONG;
typedef uint64_t ULLONG;
typedef uint8_t UBYTE;
#endif // CCX_PLATFORM_H

View File

@@ -1105,17 +1105,21 @@ int process608(const unsigned char *data, int length, void *private_data, struct
struct ccx_decoder_608_context *context;
int i;
if (dec_ctx->current_field == 1)
if (dec_ctx->current_field == 1 && (dec_ctx->extract == 1 || dec_ctx->extract == 12))
{
context = dec_ctx->context_cc608_field_1;
}
else if (dec_ctx->current_field == 2 && (dec_ctx->extract == 2 || dec_ctx->extract == 12))
{
context = dec_ctx->context_cc608_field_2;
}
else if (dec_ctx->current_field == 2 && dec_ctx->extract == 1)
{
context = NULL;
}
else
{
context = dec_ctx->context_cc608_field_2;
return -1;
}
if (context)
{

File diff suppressed because it is too large Load Diff

View File

@@ -28,55 +28,55 @@
#define CCX_DTVCC_NO_LAST_SEQUENCE -1
enum CCX_DTVCC_COMMANDS_C0_CODES
enum DTVCC_COMMANDS_C0_CODES
{
CCX_DTVCC_C0_NUL = 0x00,
CCX_DTVCC_C0_ETX = 0x03,
CCX_DTVCC_C0_BS = 0x08,
CCX_DTVCC_C0_FF = 0x0c,
CCX_DTVCC_C0_CR = 0x0d,
CCX_DTVCC_C0_HCR = 0x0e,
CCX_DTVCC_C0_EXT1 = 0x10,
CCX_DTVCC_C0_P16 = 0x18
DTVCC_C0_NUL = 0x00,
DTVCC_C0_ETX = 0x03,
DTVCC_C0_BS = 0x08,
DTVCC_C0_FF = 0x0c,
DTVCC_C0_CR = 0x0d,
DTVCC_C0_HCR = 0x0e,
DTVCC_C0_EXT1 = 0x10,
DTVCC_C0_P16 = 0x18
};
enum CCX_DTVCC_COMMANDS_C1_CODES
enum DTVCC_COMMANDS_C1_CODES
{
CCX_DTVCC_C1_CW0 = 0x80,
CCX_DTVCC_C1_CW1 = 0x81,
CCX_DTVCC_C1_CW2 = 0x82,
CCX_DTVCC_C1_CW3 = 0x83,
CCX_DTVCC_C1_CW4 = 0x84,
CCX_DTVCC_C1_CW5 = 0x85,
CCX_DTVCC_C1_CW6 = 0x86,
CCX_DTVCC_C1_CW7 = 0x87,
CCX_DTVCC_C1_CLW = 0x88,
CCX_DTVCC_C1_DSW = 0x89,
CCX_DTVCC_C1_HDW = 0x8A,
CCX_DTVCC_C1_TGW = 0x8B,
CCX_DTVCC_C1_DLW = 0x8C,
CCX_DTVCC_C1_DLY = 0x8D,
CCX_DTVCC_C1_DLC = 0x8E,
CCX_DTVCC_C1_RST = 0x8F,
CCX_DTVCC_C1_SPA = 0x90,
CCX_DTVCC_C1_SPC = 0x91,
CCX_DTVCC_C1_SPL = 0x92,
CCX_DTVCC_C1_RSV93 = 0x93,
CCX_DTVCC_C1_RSV94 = 0x94,
CCX_DTVCC_C1_RSV95 = 0x95,
CCX_DTVCC_C1_RSV96 = 0x96,
CCX_DTVCC_C1_SWA = 0x97,
CCX_DTVCC_C1_DF0 = 0x98,
CCX_DTVCC_C1_DF1 = 0x99,
CCX_DTVCC_C1_DF2 = 0x9A,
CCX_DTVCC_C1_DF3 = 0x9B,
CCX_DTVCC_C1_DF4 = 0x9C,
CCX_DTVCC_C1_DF5 = 0x9D,
CCX_DTVCC_C1_DF6 = 0x9E,
CCX_DTVCC_C1_DF7 = 0x9F
DTVCC_C1_CW0 = 0x80,
DTVCC_C1_CW1 = 0x81,
DTVCC_C1_CW2 = 0x82,
DTVCC_C1_CW3 = 0x83,
DTVCC_C1_CW4 = 0x84,
DTVCC_C1_CW5 = 0x85,
DTVCC_C1_CW6 = 0x86,
DTVCC_C1_CW7 = 0x87,
DTVCC_C1_CLW = 0x88,
DTVCC_C1_DSW = 0x89,
DTVCC_C1_HDW = 0x8A,
DTVCC_C1_TGW = 0x8B,
DTVCC_C1_DLW = 0x8C,
DTVCC_C1_DLY = 0x8D,
DTVCC_C1_DLC = 0x8E,
DTVCC_C1_RST = 0x8F,
DTVCC_C1_SPA = 0x90,
DTVCC_C1_SPC = 0x91,
DTVCC_C1_SPL = 0x92,
DTVCC_C1_RSV93 = 0x93,
DTVCC_C1_RSV94 = 0x94,
DTVCC_C1_RSV95 = 0x95,
DTVCC_C1_RSV96 = 0x96,
DTVCC_C1_SWA = 0x97,
DTVCC_C1_DF0 = 0x98,
DTVCC_C1_DF1 = 0x99,
DTVCC_C1_DF2 = 0x9A,
DTVCC_C1_DF3 = 0x9B,
DTVCC_C1_DF4 = 0x9C,
DTVCC_C1_DF5 = 0x9D,
DTVCC_C1_DF6 = 0x9E,
DTVCC_C1_DF7 = 0x9F
};
struct CCX_DTVCC_S_COMMANDS_C1
struct DTVCC_S_COMMANDS_C1
{
int code;
const char *name;
@@ -84,142 +84,142 @@ struct CCX_DTVCC_S_COMMANDS_C1
int length;
};
enum ccx_dtvcc_window_justify
enum dtvcc_window_justify
{
CCX_DTVCC_WINDOW_JUSTIFY_LEFT = 0,
CCX_DTVCC_WINDOW_JUSTIFY_RIGHT = 1,
CCX_DTVCC_WINDOW_JUSTIFY_CENTER = 2,
CCX_DTVCC_WINDOW_JUSTIFY_FULL = 3
DTVCC_WINDOW_JUSTIFY_LEFT = 0,
DTVCC_WINDOW_JUSTIFY_RIGHT = 1,
DTVCC_WINDOW_JUSTIFY_CENTER = 2,
DTVCC_WINDOW_JUSTIFY_FULL = 3
};
enum ccx_dtvcc_window_pd //Print Direction
enum dtvcc_window_pd //Print Direction
{
CCX_DTVCC_WINDOW_PD_LEFT_RIGHT = 0, //left -> right
CCX_DTVCC_WINDOW_PD_RIGHT_LEFT = 1,
CCX_DTVCC_WINDOW_PD_TOP_BOTTOM = 2,
CCX_DTVCC_WINDOW_PD_BOTTOM_TOP = 3
DTVCC_WINDOW_PD_LEFT_RIGHT = 0, //left -> right
DTVCC_WINDOW_PD_RIGHT_LEFT = 1,
DTVCC_WINDOW_PD_TOP_BOTTOM = 2,
DTVCC_WINDOW_PD_BOTTOM_TOP = 3
};
enum ccx_dtvcc_window_sd //Scroll Direction
enum dtvcc_window_sd //Scroll Direction
{
CCX_DTVCC_WINDOW_SD_LEFT_RIGHT = 0,
CCX_DTVCC_WINDOW_SD_RIGHT_LEFT = 1,
CCX_DTVCC_WINDOW_SD_TOP_BOTTOM = 2,
CCX_DTVCC_WINDOW_SD_BOTTOM_TOP = 3
DTVCC_WINDOW_SD_LEFT_RIGHT = 0,
DTVCC_WINDOW_SD_RIGHT_LEFT = 1,
DTVCC_WINDOW_SD_TOP_BOTTOM = 2,
DTVCC_WINDOW_SD_BOTTOM_TOP = 3
};
enum ccx_dtvcc_window_sde //Scroll Display Effect
enum dtvcc_window_sde //Scroll Display Effect
{
CCX_DTVCC_WINDOW_SDE_SNAP = 0,
CCX_DTVCC_WINDOW_SDE_FADE = 1,
CCX_DTVCC_WINDOW_SDE_WIPE = 2
DTVCC_WINDOW_SDE_SNAP = 0,
DTVCC_WINDOW_SDE_FADE = 1,
DTVCC_WINDOW_SDE_WIPE = 2
};
enum ccx_dtvcc_window_ed //Effect Direction
enum dtvcc_window_ed //Effect Direction
{
CCX_DTVCC_WINDOW_ED_LEFT_RIGHT = 0,
CCX_DTVCC_WINDOW_ED_RIGHT_LEFT = 1,
CCX_DTVCC_WINDOW_ED_TOP_BOTTOM = 2,
CCX_DTVCC_WINDOW_ED_BOTTOM_TOP = 3
DTVCC_WINDOW_ED_LEFT_RIGHT = 0,
DTVCC_WINDOW_ED_RIGHT_LEFT = 1,
DTVCC_WINDOW_ED_TOP_BOTTOM = 2,
DTVCC_WINDOW_ED_BOTTOM_TOP = 3
};
enum ccx_dtvcc_window_fo //Fill Opacity
enum dtvcc_window_fo //Fill Opacity
{
CCX_DTVCC_WINDOW_FO_SOLID = 0,
CCX_DTVCC_WINDOW_FO_FLASH = 1,
CCX_DTVCC_WINDOW_FO_TRANSLUCENT = 2,
CCX_DTVCC_WINDOW_FO_TRANSPARENT = 3
DTVCC_WINDOW_FO_SOLID = 0,
DTVCC_WINDOW_FO_FLASH = 1,
DTVCC_WINDOW_FO_TRANSLUCENT = 2,
DTVCC_WINDOW_FO_TRANSPARENT = 3
};
enum ccx_dtvcc_window_border
enum dtvcc_window_border
{
CCX_DTVCC_WINDOW_BORDER_NONE = 0,
CCX_DTVCC_WINDOW_BORDER_RAISED = 1,
CCX_DTVCC_WINDOW_BORDER_DEPRESSED = 2,
CCX_DTVCC_WINDOW_BORDER_UNIFORM = 3,
CCX_DTVCC_WINDOW_BORDER_SHADOW_LEFT = 4,
CCX_DTVCC_WINDOW_BORDER_SHADOW_RIGHT = 5
DTVCC_WINDOW_BORDER_NONE = 0,
DTVCC_WINDOW_BORDER_RAISED = 1,
DTVCC_WINDOW_BORDER_DEPRESSED = 2,
DTVCC_WINDOW_BORDER_UNIFORM = 3,
DTVCC_WINDOW_BORDER_SHADOW_LEFT = 4,
DTVCC_WINDOW_BORDER_SHADOW_RIGHT = 5
};
enum ccx_dtvcc_pen_size
enum dtvcc_pen_size
{
CCX_DTVCC_PEN_SIZE_SMALL = 0,
CCX_DTVCC_PEN_SIZE_STANDART = 1,
CCX_DTVCC_PEN_SIZE_LARGE = 2
DTVCC_PEN_SIZE_SMALL = 0,
DTVCC_PEN_SIZE_STANDART = 1,
DTVCC_PEN_SIZE_LARGE = 2
};
enum ccx_dtvcc_pen_font_style
enum dtvcc_pen_font_style
{
CCX_DTVCC_PEN_FONT_STYLE_DEFAULT_OR_UNDEFINED = 0,
CCX_DTVCC_PEN_FONT_STYLE_MONOSPACED_WITH_SERIFS = 1,
CCX_DTVCC_PEN_FONT_STYLE_PROPORTIONALLY_SPACED_WITH_SERIFS = 2,
CCX_DTVCC_PEN_FONT_STYLE_MONOSPACED_WITHOUT_SERIFS = 3,
CCX_DTVCC_PEN_FONT_STYLE_PROPORTIONALLY_SPACED_WITHOUT_SERIFS = 4,
CCX_DTVCC_PEN_FONT_STYLE_CASUAL_FONT_TYPE = 5,
CCX_DTVCC_PEN_FONT_STYLE_CURSIVE_FONT_TYPE = 6,
CCX_DTVCC_PEN_FONT_STYLE_SMALL_CAPITALS = 7
DTVCC_PEN_FONT_STYLE_DEFAULT_OR_UNDEFINED = 0,
DTVCC_PEN_FONT_STYLE_MONOSPACED_WITH_SERIFS = 1,
DTVCC_PEN_FONT_STYLE_PROPORTIONALLY_SPACED_WITH_SERIFS = 2,
DTVCC_PEN_FONT_STYLE_MONOSPACED_WITHOUT_SERIFS = 3,
DTVCC_PEN_FONT_STYLE_PROPORTIONALLY_SPACED_WITHOUT_SERIFS = 4,
DTVCC_PEN_FONT_STYLE_CASUAL_FONT_TYPE = 5,
DTVCC_PEN_FONT_STYLE_CURSIVE_FONT_TYPE = 6,
DTVCC_PEN_FONT_STYLE_SMALL_CAPITALS = 7
};
enum ccx_dtvcc_pen_text_tag
enum dtvcc_pen_text_tag
{
CCX_DTVCC_PEN_TEXT_TAG_DIALOG = 0,
CCX_DTVCC_PEN_TEXT_TAG_SOURCE_OR_SPEAKER_ID = 1,
CCX_DTVCC_PEN_TEXT_TAG_ELECTRONIC_VOICE = 2,
CCX_DTVCC_PEN_TEXT_TAG_FOREIGN_LANGUAGE = 3,
CCX_DTVCC_PEN_TEXT_TAG_VOICEOVER = 4,
CCX_DTVCC_PEN_TEXT_TAG_AUDIBLE_TRANSLATION = 5,
CCX_DTVCC_PEN_TEXT_TAG_SUBTITLE_TRANSLATION = 6,
CCX_DTVCC_PEN_TEXT_TAG_VOICE_QUALITY_DESCRIPTION = 7,
CCX_DTVCC_PEN_TEXT_TAG_SONG_LYRICS = 8,
CCX_DTVCC_PEN_TEXT_TAG_SOUND_EFFECT_DESCRIPTION = 9,
CCX_DTVCC_PEN_TEXT_TAG_MUSICAL_SCORE_DESCRIPTION = 10,
CCX_DTVCC_PEN_TEXT_TAG_EXPLETIVE = 11,
CCX_DTVCC_PEN_TEXT_TAG_UNDEFINED_12 = 12,
CCX_DTVCC_PEN_TEXT_TAG_UNDEFINED_13 = 13,
CCX_DTVCC_PEN_TEXT_TAG_UNDEFINED_14 = 14,
CCX_DTVCC_PEN_TEXT_TAG_NOT_TO_BE_DISPLAYED = 15
DTVCC_PEN_TEXT_TAG_DIALOG = 0,
DTVCC_PEN_TEXT_TAG_SOURCE_OR_SPEAKER_ID = 1,
DTVCC_PEN_TEXT_TAG_ELECTRONIC_VOICE = 2,
DTVCC_PEN_TEXT_TAG_FOREIGN_LANGUAGE = 3,
DTVCC_PEN_TEXT_TAG_VOICEOVER = 4,
DTVCC_PEN_TEXT_TAG_AUDIBLE_TRANSLATION = 5,
DTVCC_PEN_TEXT_TAG_SUBTITLE_TRANSLATION = 6,
DTVCC_PEN_TEXT_TAG_VOICE_QUALITY_DESCRIPTION = 7,
DTVCC_PEN_TEXT_TAG_SONG_LYRICS = 8,
DTVCC_PEN_TEXT_TAG_SOUND_EFFECT_DESCRIPTION = 9,
DTVCC_PEN_TEXT_TAG_MUSICAL_SCORE_DESCRIPTION = 10,
DTVCC_PEN_TEXT_TAG_EXPLETIVE = 11,
DTVCC_PEN_TEXT_TAG_UNDEFINED_12 = 12,
DTVCC_PEN_TEXT_TAG_UNDEFINED_13 = 13,
DTVCC_PEN_TEXT_TAG_UNDEFINED_14 = 14,
DTVCC_PEN_TEXT_TAG_NOT_TO_BE_DISPLAYED = 15
};
enum ccx_dtvcc_pen_offset
enum dtvcc_pen_offset
{
CCX_DTVCC_PEN_OFFSET_SUBSCRIPT = 0,
CCX_DTVCC_PEN_OFFSET_NORMAL = 1,
CCX_DTVCC_PEN_OFFSET_SUPERSCRIPT = 2
DTVCC_PEN_OFFSET_SUBSCRIPT = 0,
DTVCC_PEN_OFFSET_NORMAL = 1,
DTVCC_PEN_OFFSET_SUPERSCRIPT = 2
};
enum ccx_dtvcc_pen_edge
enum dtvcc_pen_edge
{
CCX_DTVCC_PEN_EDGE_NONE = 0,
CCX_DTVCC_PEN_EDGE_RAISED = 1,
CCX_DTVCC_PEN_EDGE_DEPRESSED = 2,
CCX_DTVCC_PEN_EDGE_UNIFORM = 3,
CCX_DTVCC_PEN_EDGE_LEFT_DROP_SHADOW = 4,
CCX_DTVCC_PEN_EDGE_RIGHT_DROP_SHADOW = 5
DTVCC_PEN_EDGE_NONE = 0,
DTVCC_PEN_EDGE_RAISED = 1,
DTVCC_PEN_EDGE_DEPRESSED = 2,
DTVCC_PEN_EDGE_UNIFORM = 3,
DTVCC_PEN_EDGE_LEFT_DROP_SHADOW = 4,
DTVCC_PEN_EDGE_RIGHT_DROP_SHADOW = 5
};
enum ccx_dtvcc_pen_anchor_point
enum dtvcc_pen_anchor_point
{
CCX_DTVCC_ANCHOR_POINT_TOP_LEFT = 0,
CCX_DTVCC_ANCHOR_POINT_TOP_CENTER = 1,
CCX_DTVCC_ANCHOR_POINT_TOP_RIGHT = 2,
CCX_DTVCC_ANCHOR_POINT_MIDDLE_LEFT = 3,
CCX_DTVCC_ANCHOR_POINT_MIDDLE_CENTER = 4,
CCX_DTVCC_ANCHOR_POINT_MIDDLE_RIGHT = 5,
CCX_DTVCC_ANCHOR_POINT_BOTTOM_LEFT = 6,
CCX_DTVCC_ANCHOR_POINT_BOTTOM_CENTER = 7,
CCX_DTVCC_ANCHOR_POINT_BOTTOM_RIGHT = 8
DTVCC_ANCHOR_POINT_TOP_LEFT = 0,
DTVCC_ANCHOR_POINT_TOP_CENTER = 1,
DTVCC_ANCHOR_POINT_TOP_RIGHT = 2,
DTVCC_ANCHOR_POINT_MIDDLE_LEFT = 3,
DTVCC_ANCHOR_POINT_MIDDLE_CENTER = 4,
DTVCC_ANCHOR_POINT_MIDDLE_RIGHT = 5,
DTVCC_ANCHOR_POINT_BOTTOM_LEFT = 6,
DTVCC_ANCHOR_POINT_BOTTOM_CENTER = 7,
DTVCC_ANCHOR_POINT_BOTTOM_RIGHT = 8
};
typedef struct ccx_dtvcc_pen_color
typedef struct dtvcc_pen_color
{
int fg_color;
int fg_opacity;
int bg_color;
int bg_opacity;
int edge_color;
} ccx_dtvcc_pen_color;
} dtvcc_pen_color;
typedef struct ccx_dtvcc_pen_attribs
typedef struct dtvcc_pen_attribs
{
int pen_size;
int offset;
@@ -228,9 +228,9 @@ typedef struct ccx_dtvcc_pen_attribs
int edge_type;
int underline;
int italic;
} ccx_dtvcc_pen_attribs;
} dtvcc_pen_attribs;
typedef struct ccx_dtvcc_window_attribs
typedef struct dtvcc_window_attribs
{
int justify;
int print_direction;
@@ -243,18 +243,18 @@ typedef struct ccx_dtvcc_window_attribs
int fill_opacity;
int border_type;
int border_color;
} ccx_dtvcc_window_attribs;
} dtvcc_window_attribs;
/**
* Since 1-byte and 2-byte symbols could appear in captions and
* since we have to keep symbols alignment and several windows could appear on a screen at one time,
* we use special structure for holding symbols
*/
typedef struct ccx_dtvcc_symbol
typedef struct dtvcc_symbol
{
unsigned short sym; //symbol itself, at least 16 bit
unsigned char init; //initialized or not. could be 0 or 1
} ccx_dtvcc_symbol;
} dtvcc_symbol;
#define CCX_DTVCC_SYM_SET(x, c) {x.init = 1; x.sym = c;}
#define CCX_DTVCC_SYM_SET_16(x, c1, c2) {x.init = 1; x.sym = (c1 << 8) | c2;}
@@ -262,7 +262,7 @@ typedef struct ccx_dtvcc_symbol
#define CCX_DTVCC_SYM_IS_EMPTY(x) (x.init == 0)
#define CCX_DTVCC_SYM_IS_SET(x) (x.init == 1)
typedef struct ccx_dtvcc_window
typedef struct dtvcc_window
{
int is_defined;
int number;
@@ -279,25 +279,25 @@ typedef struct ccx_dtvcc_window
int pen_style;
int win_style;
unsigned char commands[6]; // Commands used to create this window
ccx_dtvcc_window_attribs attribs;
dtvcc_window_attribs attribs;
int pen_row;
int pen_column;
ccx_dtvcc_symbol *rows[CCX_DTVCC_MAX_ROWS];
ccx_dtvcc_pen_color pen_colors[CCX_DTVCC_MAX_ROWS][CCX_DTVCC_SCREENGRID_COLUMNS];
ccx_dtvcc_pen_attribs pen_attribs[CCX_DTVCC_MAX_ROWS][CCX_DTVCC_SCREENGRID_COLUMNS];
ccx_dtvcc_pen_color pen_color_pattern;
ccx_dtvcc_pen_attribs pen_attribs_pattern;
dtvcc_symbol *rows[CCX_DTVCC_MAX_ROWS];
dtvcc_pen_color pen_colors[CCX_DTVCC_MAX_ROWS][CCX_DTVCC_SCREENGRID_COLUMNS];
dtvcc_pen_attribs pen_attribs[CCX_DTVCC_MAX_ROWS][CCX_DTVCC_SCREENGRID_COLUMNS];
dtvcc_pen_color pen_color_pattern;
dtvcc_pen_attribs pen_attribs_pattern;
int memory_reserved;
int is_empty;
LLONG time_ms_show;
LLONG time_ms_hide;
} ccx_dtvcc_window;
} dtvcc_window;
typedef struct dtvcc_tv_screen
{
ccx_dtvcc_symbol chars[CCX_DTVCC_SCREENGRID_ROWS][CCX_DTVCC_SCREENGRID_COLUMNS];
ccx_dtvcc_pen_color pen_colors[CCX_DTVCC_SCREENGRID_ROWS][CCX_DTVCC_SCREENGRID_COLUMNS];
ccx_dtvcc_pen_attribs pen_attribs[CCX_DTVCC_SCREENGRID_ROWS][CCX_DTVCC_SCREENGRID_COLUMNS];
dtvcc_symbol chars[CCX_DTVCC_SCREENGRID_ROWS][CCX_DTVCC_SCREENGRID_COLUMNS];
dtvcc_pen_color pen_colors[CCX_DTVCC_SCREENGRID_ROWS][CCX_DTVCC_SCREENGRID_COLUMNS];
dtvcc_pen_attribs pen_attribs[CCX_DTVCC_SCREENGRID_ROWS][CCX_DTVCC_SCREENGRID_COLUMNS];
LLONG time_ms_show;
LLONG time_ms_hide;
unsigned int cc_count;
@@ -314,13 +314,13 @@ typedef struct ccx_decoder_dtvcc_report
unsigned services[CCX_DTVCC_MAX_SERVICES];
} ccx_decoder_dtvcc_report;
typedef struct ccx_dtvcc_service_decoder
typedef struct dtvcc_service_decoder
{
ccx_dtvcc_window windows[CCX_DTVCC_MAX_WINDOWS];
dtvcc_window windows[CCX_DTVCC_MAX_WINDOWS];
int current_window;
dtvcc_tv_screen *tv;
int cc_count;
} ccx_dtvcc_service_decoder;
} dtvcc_service_decoder;
typedef struct ccx_decoder_dtvcc_settings
{
@@ -339,7 +339,7 @@ typedef struct ccx_decoder_dtvcc_settings
* decoders have to know nothing about output files
*/
typedef struct ccx_dtvcc_ctx
typedef struct dtvcc_ctx
{
int is_active;
int active_services_count;
@@ -348,7 +348,7 @@ typedef struct ccx_dtvcc_ctx
ccx_decoder_dtvcc_report *report;
ccx_dtvcc_service_decoder decoders[CCX_DTVCC_MAX_SERVICES];
dtvcc_service_decoder decoders[CCX_DTVCC_MAX_SERVICES];
unsigned char current_packet[CCX_DTVCC_MAX_PACKET_LENGTH];
int current_packet_length;
@@ -359,20 +359,84 @@ typedef struct ccx_dtvcc_ctx
void *encoder; //we can't include header, so keeping it this way
int no_rollup;
struct ccx_common_timing_ctx *timing;
} ccx_dtvcc_ctx;
} dtvcc_ctx;
void ccx_dtvcc_clear_packet(ccx_dtvcc_ctx *ctx);
void ccx_dtvcc_windows_reset(ccx_dtvcc_service_decoder *decoder);
void ccx_dtvcc_decoder_flush(ccx_dtvcc_ctx *dtvcc, ccx_dtvcc_service_decoder *decoder);
void dtvcc_clear_packet(dtvcc_ctx *ctx);
void dtvcc_windows_reset(dtvcc_service_decoder *decoder);
void dtvcc_decoder_flush(dtvcc_ctx *dtvcc, dtvcc_service_decoder *decoder);
void ccx_dtvcc_process_current_packet(ccx_dtvcc_ctx *dtvcc, int len);
void ccx_dtvcc_process_service_block(ccx_dtvcc_ctx *dtvcc,
ccx_dtvcc_service_decoder *decoder,
void dtvcc_process_current_packet(dtvcc_ctx *dtvcc, int len);
void dtvcc_process_service_block(dtvcc_ctx *dtvcc,
dtvcc_service_decoder *decoder,
unsigned char *data,
int data_length);
extern ccx_dtvcc_pen_color ccx_dtvcc_default_pen_color;
extern ccx_dtvcc_pen_attribs ccx_dtvcc_default_pen_attribs;
void dtvcc_tv_clear(dtvcc_service_decoder *decoder);
int dtvcc_decoder_has_visible_windows(dtvcc_service_decoder *decoder);
void dtvcc_window_clear_row(dtvcc_window *window, int row_index);
void dtvcc_window_clear_text(dtvcc_window *window);
void dtvcc_window_clear(dtvcc_service_decoder *decoder, int window_id);
void dtvcc_window_apply_style(dtvcc_window *window, dtvcc_window_attribs *style);
#ifdef DTVCC_PRINT_DEBUG
int dtvcc_is_win_row_empty(dtvcc_window *window, int row_index);
void dtvcc_get_win_write_interval(dtvcc_window *window, int row_index, int *first, int *last);
void dtvcc_window_dump(dtvcc_service_decoder *decoder, dtvcc_window *window);
#endif
void dtvcc_decoders_reset(dtvcc_ctx *dtvcc);
int dtvcc_compare_win_priorities(const void *a, const void *b);
void dtvcc_window_update_time_show(dtvcc_window *window, struct ccx_common_timing_ctx *timing);
void dtvcc_window_update_time_hide(dtvcc_window *window, struct ccx_common_timing_ctx *timing);
void dtvcc_screen_update_time_show(dtvcc_tv_screen *tv, LLONG time);
void dtvcc_screen_update_time_hide(dtvcc_tv_screen *tv, LLONG time);
void dtvcc_get_window_dimensions(dtvcc_window *window, int *x1, int *x2, int *y1, int *y2);
int dtvcc_is_window_overlapping(dtvcc_service_decoder *decoder, dtvcc_window *window);
void dtvcc_window_copy_to_screen(dtvcc_service_decoder *decoder, dtvcc_window *window);
void dtvcc_screen_print(dtvcc_ctx *dtvcc, dtvcc_service_decoder *decoder);
void dtvcc_process_hcr(dtvcc_service_decoder *decoder);
void dtvcc_process_ff(dtvcc_service_decoder *decoder);
void dtvcc_process_etx(dtvcc_service_decoder *decoder);
void dtvcc_process_bs(dtvcc_service_decoder *decoder);
void dtvcc_window_rollup(dtvcc_service_decoder *decoder, dtvcc_window *window);
void dtvcc_process_cr(dtvcc_ctx *dtvcc, dtvcc_service_decoder *decoder);
void dtvcc_process_character(dtvcc_service_decoder *decoder, dtvcc_symbol symbol);
void dtvcc_handle_CWx_SetCurrentWindow(dtvcc_service_decoder *decoder, int window_id);
void dtvcc_handle_CLW_ClearWindows(dtvcc_ctx *dtvcc, dtvcc_service_decoder *decoder, int windows_bitmap);
void dtvcc_handle_DSW_DisplayWindows(dtvcc_service_decoder *decoder, int windows_bitmap, struct ccx_common_timing_ctx *timing);
void dtvcc_handle_HDW_HideWindows(dtvcc_ctx *dtvcc,dtvcc_service_decoder *decoder,
int windows_bitmap);
void dtvcc_handle_TGW_ToggleWindows(dtvcc_ctx *dtvcc,
dtvcc_service_decoder *decoder,
int windows_bitmap);
void dtvcc_handle_DFx_DefineWindow(dtvcc_service_decoder *decoder, int window_id, unsigned char *data, struct ccx_common_timing_ctx *timing);
void dtvcc_handle_SWA_SetWindowAttributes(dtvcc_service_decoder *decoder, unsigned char *data);
void dtvcc_handle_DLW_DeleteWindows(dtvcc_ctx *dtvcc,
dtvcc_service_decoder *decoder,
int windows_bitmap);
void dtvcc_handle_SPA_SetPenAttributes(dtvcc_service_decoder *decoder, unsigned char *data);
void dtvcc_handle_SPC_SetPenColor(dtvcc_service_decoder *decoder, unsigned char *data);
void dtvcc_handle_SPL_SetPenLocation(dtvcc_service_decoder *decoder, unsigned char *data);
void dtvcc_handle_RST_Reset(dtvcc_service_decoder *decoder);
void dtvcc_handle_DLY_Delay(dtvcc_service_decoder *decoder, int tenths_of_sec);
void dtvcc_handle_DLC_DelayCancel(dtvcc_service_decoder *decoder);
void dtvcc_handle_C0_P16(dtvcc_service_decoder *decoder, unsigned char *data);
int dtvcc_handle_G0(dtvcc_service_decoder *decoder, unsigned char *data, int data_length);
int dtvcc_handle_G1(dtvcc_service_decoder *decoder, unsigned char *data, int data_length);
int dtvcc_handle_C0(dtvcc_ctx *dtvcc,
dtvcc_service_decoder *decoder,
unsigned char *data,
int data_length);
int dtvcc_handle_C1(dtvcc_ctx *dtvcc,
dtvcc_service_decoder *decoder,
unsigned char *data,
int data_length);
int dtvcc_handle_C2(dtvcc_service_decoder *decoder, unsigned char *data, int data_length);
int dtvcc_handle_C3(dtvcc_service_decoder *decoder, unsigned char *data, int data_length);
int dtvcc_handle_extended_char(dtvcc_service_decoder *decoder, unsigned char *data, int data_length);
extern dtvcc_pen_color dtvcc_default_pen_color;
extern dtvcc_pen_attribs dtvcc_default_pen_attribs;
#endif

View File

@@ -4,7 +4,11 @@
#include "utility.h"
#include "ccx_common_common.h"
int _dtvcc_is_row_empty(dtvcc_tv_screen *tv, int row_index)
#if !defined(DISABLE_RUST) && defined(WIN32)
extern void ccxr_close_handle(void *handle);
#endif
int dtvcc_is_row_empty(dtvcc_tv_screen *tv, int row_index)
{
for (int j = 0; j < CCX_DTVCC_SCREENGRID_COLUMNS; j++)
{
@@ -14,11 +18,11 @@ int _dtvcc_is_row_empty(dtvcc_tv_screen *tv, int row_index)
return 1;
}
int _dtvcc_is_screen_empty(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
int dtvcc_is_screen_empty(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
{
for (int i = 0; i < CCX_DTVCC_SCREENGRID_ROWS; i++)
{
if (!_dtvcc_is_row_empty(tv, i))
if (!dtvcc_is_row_empty(tv, i))
{
// we will write subtitle
encoder->cea_708_counter++;
@@ -28,7 +32,7 @@ int _dtvcc_is_screen_empty(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
return 1;
}
void _dtvcc_get_write_interval(dtvcc_tv_screen *tv, int row_index, int *first, int *last)
void dtvcc_get_write_interval(dtvcc_tv_screen *tv, int row_index, int *first, int *last)
{
for (*first = 0; *first < CCX_DTVCC_SCREENGRID_COLUMNS; (*first)++)
if (CCX_DTVCC_SYM_IS_SET(tv->chars[row_index][*first]))
@@ -38,7 +42,7 @@ void _dtvcc_get_write_interval(dtvcc_tv_screen *tv, int row_index, int *first, i
break;
}
void _dtvcc_color_to_hex(int color, unsigned *hR, unsigned *hG, unsigned *hB)
void dtvcc_color_to_hex(int color, unsigned *hR, unsigned *hG, unsigned *hB)
{
*hR = (unsigned)(color >> 4);
*hG = (unsigned)((color >> 2) & 0x3);
@@ -47,16 +51,16 @@ void _dtvcc_color_to_hex(int color, unsigned *hR, unsigned *hG, unsigned *hB)
color, color, *hR, *hG, *hB);
}
void _dtvcc_change_pen_colors(dtvcc_tv_screen *tv, ccx_dtvcc_pen_color pen_color, int row_index, int column_index, struct encoder_ctx *encoder, size_t *buf_len, int open)
void dtvcc_change_pen_colors(dtvcc_tv_screen *tv, dtvcc_pen_color pen_color, int row_index, int column_index, struct encoder_ctx *encoder, size_t *buf_len, int open)
{
if (encoder->no_font_color)
return;
char *buf = (char *)encoder->buffer;
ccx_dtvcc_pen_color new_pen_color;
dtvcc_pen_color new_pen_color;
if (column_index >= CCX_DTVCC_SCREENGRID_COLUMNS)
new_pen_color = ccx_dtvcc_default_pen_color;
new_pen_color = dtvcc_default_pen_color;
else
new_pen_color = tv->pen_colors[row_index][column_index];
if (pen_color.fg_color != new_pen_color.fg_color)
@@ -67,7 +71,7 @@ void _dtvcc_change_pen_colors(dtvcc_tv_screen *tv, ccx_dtvcc_pen_color pen_color
if (new_pen_color.fg_color != 0x3f && open)
{
unsigned red, green, blue;
_dtvcc_color_to_hex(new_pen_color.fg_color, &red, &green, &blue);
dtvcc_color_to_hex(new_pen_color.fg_color, &red, &green, &blue);
red = (255 / 3) * red;
green = (255 / 3) * green;
blue = (255 / 3) * blue;
@@ -76,16 +80,16 @@ void _dtvcc_change_pen_colors(dtvcc_tv_screen *tv, ccx_dtvcc_pen_color pen_color
}
}
void _dtvcc_change_pen_attribs(dtvcc_tv_screen *tv, ccx_dtvcc_pen_attribs pen_attribs, int row_index, int column_index, struct encoder_ctx *encoder, size_t *buf_len, int open)
void dtvcc_change_pen_attribs(dtvcc_tv_screen *tv, dtvcc_pen_attribs pen_attribs, int row_index, int column_index, struct encoder_ctx *encoder, size_t *buf_len, int open)
{
if (encoder->no_font_color)
return;
char *buf = (char *)encoder->buffer;
ccx_dtvcc_pen_attribs new_pen_attribs;
dtvcc_pen_attribs new_pen_attribs;
if (column_index >= CCX_DTVCC_SCREENGRID_COLUMNS)
new_pen_attribs = ccx_dtvcc_default_pen_attribs;
new_pen_attribs = dtvcc_default_pen_attribs;
else
new_pen_attribs = tv->pen_attribs[row_index][column_index];
if (pen_attribs.italic != new_pen_attribs.italic)
@@ -119,7 +123,7 @@ size_t write_utf16_char(unsigned short utf16_char, char *out)
}
}
void _dtvcc_write_row(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *decoder, int row_index, struct encoder_ctx *encoder, int use_colors)
void dtvcc_write_row(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, int row_index, struct encoder_ctx *encoder, int use_colors)
{
dtvcc_tv_screen *tv = decoder->tv;
char *buf = (char *)encoder->buffer;
@@ -129,19 +133,19 @@ void _dtvcc_write_row(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *d
int fd = encoder->dtvcc_writers[tv->service_number - 1].fd;
ccx_dtvcc_pen_color pen_color = ccx_dtvcc_default_pen_color;
ccx_dtvcc_pen_attribs pen_attribs = ccx_dtvcc_default_pen_attribs;
_dtvcc_get_write_interval(tv, row_index, &first, &last);
dtvcc_pen_color pen_color = dtvcc_default_pen_color;
dtvcc_pen_attribs pen_attribs = dtvcc_default_pen_attribs;
dtvcc_get_write_interval(tv, row_index, &first, &last);
for (int i = 0; i < last + 1; i++)
{
if (use_colors)
_dtvcc_change_pen_colors(tv, pen_color, row_index, i, encoder, &buf_len, 0);
_dtvcc_change_pen_attribs(tv, pen_attribs, row_index, i, encoder, &buf_len, 0);
_dtvcc_change_pen_attribs(tv, pen_attribs, row_index, i, encoder, &buf_len, 1);
dtvcc_change_pen_colors(tv, pen_color, row_index, i, encoder, &buf_len, 0);
dtvcc_change_pen_attribs(tv, pen_attribs, row_index, i, encoder, &buf_len, 0);
dtvcc_change_pen_attribs(tv, pen_attribs, row_index, i, encoder, &buf_len, 1);
if (use_colors)
_dtvcc_change_pen_colors(tv, pen_color, row_index, i, encoder, &buf_len, 1);
dtvcc_change_pen_colors(tv, pen_color, row_index, i, encoder, &buf_len, 1);
pen_color = tv->pen_colors[row_index][i];
pen_attribs = tv->pen_attribs[row_index][i];
@@ -159,8 +163,8 @@ void _dtvcc_write_row(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *d
// there can be unclosed tags or colors after the last symbol in a row
if (use_colors)
_dtvcc_change_pen_colors(tv, pen_color, row_index, CCX_DTVCC_SCREENGRID_COLUMNS, encoder, &buf_len, 0);
_dtvcc_change_pen_attribs(tv, pen_attribs, row_index, CCX_DTVCC_SCREENGRID_COLUMNS, encoder, &buf_len, 0);
dtvcc_change_pen_colors(tv, pen_color, row_index, CCX_DTVCC_SCREENGRID_COLUMNS, encoder, &buf_len, 0);
dtvcc_change_pen_attribs(tv, pen_attribs, row_index, CCX_DTVCC_SCREENGRID_COLUMNS, encoder, &buf_len, 0);
// Tags can still be crossed e.g <f><i>text</f></i>, but testing HTML code has shown that they still are handled correctly.
// In case of errors fix it once and for all.
@@ -168,7 +172,7 @@ void _dtvcc_write_row(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *d
{
char *encoded_buf = calloc(INITIAL_ENC_BUFFER_CAPACITY, sizeof(char));
if (!encoded_buf)
ccx_common_logging.fatal_ftn(EXIT_NOT_ENOUGH_MEMORY, "_dtvcc_write_row");
ccx_common_logging.fatal_ftn(EXIT_NOT_ENOUGH_MEMORY, "dtvcc_write_row");
char *encoded_buf_start = encoded_buf;
@@ -178,7 +182,7 @@ void _dtvcc_write_row(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *d
size_t result = iconv(writer->cd, &buf, &in_bytes_left, &encoded_buf, &out_bytes_left);
if (result == -1)
ccx_common_logging.log_ftn("[CEA-708] _dtvcc_write_row: "
ccx_common_logging.log_ftn("[CEA-708] dtvcc_write_row: "
"conversion failed: %s\n",
strerror(errno));
@@ -192,10 +196,10 @@ void _dtvcc_write_row(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *d
}
}
void ccx_dtvcc_write_srt(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
void dtvcc_write_srt(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
{
dtvcc_tv_screen *tv = decoder->tv;
if (_dtvcc_is_screen_empty(tv, encoder))
if (dtvcc_is_screen_empty(tv, encoder))
return;
if (tv->time_ms_show + encoder->subs_delay < 0)
@@ -216,9 +220,9 @@ void ccx_dtvcc_write_srt(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder
for (int i = 0; i < CCX_DTVCC_SCREENGRID_ROWS; i++)
{
if (!_dtvcc_is_row_empty(tv, i))
if (!dtvcc_is_row_empty(tv, i))
{
_dtvcc_write_row(writer, decoder, i, encoder, 1);
dtvcc_write_row(writer, decoder, i, encoder, 1);
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd,
encoder->encoded_crlf, encoder->encoded_crlf_length);
}
@@ -227,7 +231,7 @@ void ccx_dtvcc_write_srt(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder
encoder->encoded_crlf, encoder->encoded_crlf_length);
}
void ccx_dtvcc_write_debug(dtvcc_tv_screen *tv)
void dtvcc_write_debug(dtvcc_tv_screen *tv)
{
char tbuf1[SUBLINESIZE],
tbuf2[SUBLINESIZE];
@@ -238,10 +242,10 @@ void ccx_dtvcc_write_debug(dtvcc_tv_screen *tv)
ccx_common_logging.debug_ftn(CCX_DMT_GENERIC_NOTICES, "\r%s --> %s\n", tbuf1, tbuf2);
for (int i = 0; i < CCX_DTVCC_SCREENGRID_ROWS; i++)
{
if (!_dtvcc_is_row_empty(tv, i))
if (!dtvcc_is_row_empty(tv, i))
{
int first, last;
_dtvcc_get_write_interval(tv, i, &first, &last);
dtvcc_get_write_interval(tv, i, &first, &last);
for (int j = first; j <= last; j++)
ccx_common_logging.debug_ftn(CCX_DMT_GENERIC_NOTICES, "%c", tv->chars[i][j]);
ccx_common_logging.debug_ftn(CCX_DMT_GENERIC_NOTICES, "\n");
@@ -249,10 +253,10 @@ void ccx_dtvcc_write_debug(dtvcc_tv_screen *tv)
}
}
void ccx_dtvcc_write_transcript(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
void dtvcc_write_transcript(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
{
dtvcc_tv_screen *tv = decoder->tv;
if (_dtvcc_is_screen_empty(tv, encoder))
if (dtvcc_is_screen_empty(tv, encoder))
return;
if (tv->time_ms_show + encoder->subs_delay < 0) // Drop screens that because of subs_delay start too early
@@ -262,7 +266,7 @@ void ccx_dtvcc_write_transcript(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_
for (int i = 0; i < CCX_DTVCC_SCREENGRID_ROWS; i++)
{
if (!_dtvcc_is_row_empty(tv, i))
if (!dtvcc_is_row_empty(tv, i))
{
buf[0] = 0;
@@ -284,14 +288,14 @@ void ccx_dtvcc_write_transcript(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_
if (buf_len != 0)
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, buf_len);
_dtvcc_write_row(writer, decoder, i, encoder, 0);
dtvcc_write_row(writer, decoder, i, encoder, 0);
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd,
encoder->encoded_crlf, encoder->encoded_crlf_length);
}
}
}
void _dtvcc_write_sami_header(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
void dtvcc_write_sami_header(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
{
char *buf = (char *)encoder->buffer;
memset(buf, 0, INITIAL_ENC_BUFFER_CAPACITY);
@@ -316,7 +320,7 @@ void _dtvcc_write_sami_header(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, buf_len);
}
void _dtvcc_write_sami_footer(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
void dtvcc_write_sami_footer(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
{
char *buf = (char *)encoder->buffer;
sprintf(buf, "</body></sami>");
@@ -325,17 +329,17 @@ void _dtvcc_write_sami_footer(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
encoder->encoded_crlf, encoder->encoded_crlf_length);
}
void ccx_dtvcc_write_sami(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
void dtvcc_write_sami(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
{
dtvcc_tv_screen *tv = decoder->tv;
if (_dtvcc_is_screen_empty(tv, encoder))
if (dtvcc_is_screen_empty(tv, encoder))
return;
if (tv->time_ms_show + encoder->subs_delay < 0)
return;
if (tv->cc_count == 1)
_dtvcc_write_sami_header(tv, encoder);
dtvcc_write_sami_header(tv, encoder);
char *buf = (char *)encoder->buffer;
@@ -347,9 +351,9 @@ void ccx_dtvcc_write_sami(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decode
for (int i = 0; i < CCX_DTVCC_SCREENGRID_ROWS; i++)
{
if (!_dtvcc_is_row_empty(tv, i))
if (!dtvcc_is_row_empty(tv, i))
{
_dtvcc_write_row(writer, decoder, i, encoder, 1);
dtvcc_write_row(writer, decoder, i, encoder, 1);
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd,
encoder->encoded_br, encoder->encoded_br_length);
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd,
@@ -363,52 +367,52 @@ void ccx_dtvcc_write_sami(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decode
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, strlen(buf));
}
void _ccx_dtvcc_write(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
void dtvcc_write(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
{
switch (encoder->write_format)
{
case CCX_OF_NULL:
break;
case CCX_OF_SRT:
ccx_dtvcc_write_srt(writer, decoder, encoder);
dtvcc_write_srt(writer, decoder, encoder);
break;
case CCX_OF_TRANSCRIPT:
ccx_dtvcc_write_transcript(writer, decoder, encoder);
dtvcc_write_transcript(writer, decoder, encoder);
break;
case CCX_OF_SAMI:
ccx_dtvcc_write_sami(writer, decoder, encoder);
dtvcc_write_sami(writer, decoder, encoder);
break;
case CCX_OF_MCC:
printf("REALLY BAD... [%s:%d]\n", __FILE__, __LINE__);
break;
default:
ccx_dtvcc_write_debug(decoder->tv);
dtvcc_write_debug(decoder->tv);
break;
}
}
void ccx_dtvcc_write_done(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
void dtvcc_write_done(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
{
switch (encoder->write_format)
{
case CCX_OF_SAMI:
_dtvcc_write_sami_footer(tv, encoder);
dtvcc_write_sami_footer(tv, encoder);
break;
default:
ccx_common_logging.debug_ftn(
CCX_DMT_708, "[CEA-708] ccx_dtvcc_write_done: no handling required\n");
CCX_DMT_708, "[CEA-708] dtvcc_write_done: no handling required\n");
break;
}
}
void ccx_dtvcc_writer_init(ccx_dtvcc_writer_ctx *writer,
char *base_filename,
int program_number,
int service_number,
enum ccx_output_format write_format,
struct encoder_cfg *cfg)
void dtvcc_writer_init(dtvcc_writer_ctx *writer,
char *base_filename,
int program_number,
int service_number,
enum ccx_output_format write_format,
struct encoder_cfg *cfg)
{
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] ccx_dtvcc_writer_init\n");
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_writer_init\n");
writer->fd = -1;
writer->cd = (iconv_t)-1;
if ((write_format == CCX_OF_NULL) || (write_format == CCX_OF_MCC))
@@ -417,7 +421,7 @@ void ccx_dtvcc_writer_init(ccx_dtvcc_writer_ctx *writer,
return;
}
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] ccx_dtvcc_writer_init: "
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_writer_init: "
"[%s][%d][%d]\n",
base_filename, program_number, service_number);
@@ -428,12 +432,17 @@ void ccx_dtvcc_writer_init(ccx_dtvcc_writer_ctx *writer,
writer->filename = create_outfilename(base_filename, suffix, ext);
if (!writer->filename)
ccx_common_logging.fatal_ftn(
EXIT_NOT_ENOUGH_MEMORY, "[CEA-708] _dtvcc_decoder_init_write: not enough memory");
EXIT_NOT_ENOUGH_MEMORY, "[CEA-708] dtvcc_decoder_init_write: not enough memory");
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] ccx_dtvcc_writer_init: inited [%s]\n", writer->filename);
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_writer_init: inited [%s]\n", writer->filename);
char *charset = cfg->all_services_charset ? cfg->all_services_charset : cfg->services_charsets[service_number - 1];
#ifndef DISABLE_RUST
writer->fhandle = NULL;
writer->charset = charset;
#endif
if (charset)
{
writer->cd = iconv_open("UTF-8", charset);
@@ -446,10 +455,14 @@ void ccx_dtvcc_writer_init(ccx_dtvcc_writer_ctx *writer,
}
}
void ccx_dtvcc_writer_cleanup(ccx_dtvcc_writer_ctx *writer)
void dtvcc_writer_cleanup(dtvcc_writer_ctx *writer)
{
if (writer->fd >= 0 && writer->fd != STDOUT_FILENO)
close(writer->fd);
#if !defined(DISABLE_RUST) && defined(WIN32)
ccxr_close_handle(writer->fhandle);
writer->charset = NULL;
#endif
free(writer->filename);
if (writer->cd == (iconv_t)-1)
{
@@ -459,9 +472,9 @@ void ccx_dtvcc_writer_cleanup(ccx_dtvcc_writer_ctx *writer)
iconv_close(writer->cd);
}
void ccx_dtvcc_writer_output(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
void dtvcc_writer_output(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
{
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] ccx_dtvcc_writer_output: "
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_writer_output: "
"writing... [%s][%d]\n",
writer->filename, writer->fd);
@@ -471,7 +484,7 @@ void ccx_dtvcc_writer_output(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_dec
if (writer->filename && writer->fd < 0) //first request to write
{
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] "
"ccx_dtvcc_writer_output: creating %s\n",
"dtvcc_writer_output: creating %s\n",
writer->filename);
writer->fd = open(writer->filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, S_IREAD | S_IWRITE);
if (writer->fd == -1)
@@ -483,5 +496,5 @@ void ccx_dtvcc_writer_output(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_dec
write_wrapped(writer->fd, UTF8_BOM, sizeof(UTF8_BOM));
}
_ccx_dtvcc_write(writer, decoder, encoder);
dtvcc_write(writer, decoder, encoder);
}

View File

@@ -5,15 +5,31 @@
#include "ccx_encoders_common.h"
#include "ccx_common_option.h"
void ccx_dtvcc_write_done(dtvcc_tv_screen *tv, struct encoder_ctx *encoder);
void dtvcc_write_done(dtvcc_tv_screen *tv, struct encoder_ctx *encoder);
void ccx_dtvcc_writer_init(ccx_dtvcc_writer_ctx *writer,
void dtvcc_writer_init(dtvcc_writer_ctx *writer,
char *base_filename,
int program_number,
int service_number,
enum ccx_output_format write_format,
struct encoder_cfg *cfg);
void ccx_dtvcc_writer_cleanup(ccx_dtvcc_writer_ctx *writer);
void ccx_dtvcc_writer_output(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *decoder, struct encoder_ctx *encoder);
void dtvcc_writer_cleanup(dtvcc_writer_ctx *writer);
void dtvcc_writer_output(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder);
int dtvcc_is_row_empty(dtvcc_tv_screen *tv, int row_index);
int dtvcc_is_screen_empty(dtvcc_tv_screen *tv, struct encoder_ctx *encoder);
void dtvcc_get_write_interval(dtvcc_tv_screen *tv, int row_index, int *first, int *last);
void dtvcc_color_to_hex(int color, unsigned *hR, unsigned *hG, unsigned *hB);
void dtvcc_change_pen_colors(dtvcc_tv_screen *tv, dtvcc_pen_color pen_color, int row_index, int column_index, struct encoder_ctx *encoder, size_t *buf_len, int open);
void dtvcc_change_pen_attribs(dtvcc_tv_screen *tv, dtvcc_pen_attribs pen_attribs, int row_index, int column_index, struct encoder_ctx *encoder, size_t *buf_len, int open);
size_t write_utf16_char(unsigned short utf16_char, char *out);
void dtvcc_write_row(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, int row_index, struct encoder_ctx *encoder, int use_colors);
void dtvcc_write_srt(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder);
void dtvcc_write_debug(dtvcc_tv_screen *tv);
void dtvcc_write_transcript(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder);
void dtvcc_write_sami_header(dtvcc_tv_screen *tv, struct encoder_ctx *encoder);
void dtvcc_write_sami_footer(dtvcc_tv_screen *tv, struct encoder_ctx *encoder);
void dtvcc_write_sami(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder);
void dtvcc_write(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder);
#endif /*_CCX_DECODERS_708_OUTPUT_H_*/

View File

@@ -15,6 +15,11 @@ made to reuse, not duplicate, as many functions as possible */
#include "ccx_encoders_mcc.h"
#include "ccx_dtvcc.h"
#ifndef DISABLE_RUST
extern int ccxr_process_cc_data(struct lib_cc_decode *dec_ctx, unsigned char *cc_data, int cc_count);
extern void ccxr_flush_decoder(struct dtvcc_ctx *dtvcc, struct dtvcc_service_decoder *decoder);
#endif
uint64_t utc_refvalue = UINT64_MAX; /* _UI64_MAX/UINT64_MAX means don't use UNIX, 0 = use current system time as reference, +1 use a specific reference */
extern int in_xds_mode;
@@ -49,6 +54,10 @@ int process_cc_data(struct encoder_ctx *enc_ctx, struct lib_cc_decode *dec_ctx,
return 0;
}
#ifndef DISABLE_RUST
ret = ccxr_process_cc_data(dec_ctx, cc_data, cc_count);
#endif
for (int j = 0; j < cc_count * 3; j = j + 3)
{
if (validate_cc_data_pair(cc_data + j))
@@ -187,15 +196,19 @@ int do_cb(struct lib_cc_decode *ctx, unsigned char *cc_block, struct cc_subtitle
timeok = 0;
ctx->processed_enough = 1;
}
char temp[4];
temp[0] = cc_valid;
temp[1] = cc_type;
temp[2] = cc_block[1];
temp[3] = cc_block[2];
if (timeok)
{
if (ctx->write_format != CCX_OF_RCWT)
ccx_dtvcc_process_data(ctx, (const unsigned char *)temp, 4);
{
#ifdef DISABLE_RUST
char temp[4];
temp[0] = cc_valid;
temp[1] = cc_type;
temp[2] = cc_block[1];
temp[3] = cc_block[2];
dtvcc_process_data(ctx->dtvcc, (const unsigned char *)temp);
#endif
}
else
writercwtdata(ctx, cc_block, sub);
}
@@ -219,7 +232,7 @@ int do_cb(struct lib_cc_decode *ctx, unsigned char *cc_block, struct cc_subtitle
void dinit_cc_decode(struct lib_cc_decode **ctx)
{
struct lib_cc_decode *lctx = *ctx;
ccx_dtvcc_free(&lctx->dtvcc);
dtvcc_free(&lctx->dtvcc);
dinit_avc(&lctx->avc_ctx);
ccx_decoder_608_dinit_library(&lctx->context_cc608_field_1);
ccx_decoder_608_dinit_library(&lctx->context_cc608_field_2);
@@ -248,7 +261,7 @@ struct lib_cc_decode *init_cc_decode(struct ccx_decoders_common_settings_t *sett
ctx->no_rollup = setting->no_rollup;
ctx->noscte20 = setting->noscte20;
ctx->dtvcc = ccx_dtvcc_init(setting->settings_dtvcc);
ctx->dtvcc = dtvcc_init(setting->settings_dtvcc);
ctx->dtvcc->is_active = setting->settings_dtvcc->enabled;
if (setting->codec == CCX_CODEC_ATSC_CC)
@@ -432,13 +445,17 @@ void flush_cc_decode(struct lib_cc_decode *ctx, struct cc_subtitle *sub)
{
for (int i = 0; i < CCX_DTVCC_MAX_SERVICES; i++)
{
ccx_dtvcc_service_decoder *decoder = &ctx->dtvcc->decoders[i];
dtvcc_service_decoder *decoder = &ctx->dtvcc->decoders[i];
if (!ctx->dtvcc->services_active[i])
continue;
if (decoder->cc_count > 0)
{
ctx->current_field = 3;
ccx_dtvcc_decoder_flush(ctx->dtvcc, decoder);
#ifndef DISABLE_RUST
ccxr_flush_decoder(ctx->dtvcc, decoder);
#else
dtvcc_decoder_flush(ctx->dtvcc, decoder);
#endif
}
}
}
@@ -520,8 +537,8 @@ struct lib_cc_decode *copy_decoder_context(struct lib_cc_decode *ctx)
ctx_copy->private_data = NULL;
if (ctx->dtvcc)
{
ctx_copy->dtvcc = malloc(sizeof(struct ccx_dtvcc_ctx));
memcpy(ctx_copy->dtvcc, ctx->dtvcc, sizeof(struct ccx_dtvcc_ctx));
ctx_copy->dtvcc = malloc(sizeof(struct dtvcc_ctx));
memcpy(ctx_copy->dtvcc, ctx->dtvcc, sizeof(struct dtvcc_ctx));
}
if (ctx->xds_ctx)
{

View File

@@ -208,7 +208,7 @@ struct lib_cc_decode
int stat_divicom;
int false_pict_header;
ccx_dtvcc_ctx *dtvcc;
dtvcc_ctx *dtvcc;
int current_field;
// Analyse/use the picture information
int maxtref; // Use to remember the temporal reference number

View File

@@ -3,9 +3,8 @@
#include "ccx_encoders_common.h"
#include "ccx_decoders_708_output.h"
void ccx_dtvcc_process_data(struct lib_cc_decode *ctx,
const unsigned char *data,
int data_length)
void dtvcc_process_data(struct dtvcc_ctx *dtvcc,
const unsigned char *data)
{
/*
* Note: the data has following format:
@@ -14,78 +13,73 @@ void ccx_dtvcc_process_data(struct lib_cc_decode *ctx,
* 2 bytes for the actual data
*/
ccx_dtvcc_ctx *dtvcc = ctx->dtvcc;
if (!dtvcc->is_active && !dtvcc->report_enabled)
return;
for (int i = 0; i < data_length; i += 4)
unsigned char cc_valid = data[0];
unsigned char cc_type = data[1];
switch (cc_type)
{
unsigned char cc_valid = data[i];
unsigned char cc_type = data[i + 1];
switch (cc_type)
{
case 2:
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_process_data: DTVCC Channel Packet Data\n");
if (cc_valid && dtvcc->is_current_packet_header_parsed)
case 2:
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_process_data: DTVCC Channel Packet Data\n");
if (cc_valid && dtvcc->is_current_packet_header_parsed)
{
if (dtvcc->current_packet_length > 253)
{
if (dtvcc->current_packet_length > 253)
{
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_process_data: "
"Warning: Legal packet size exceeded (1), data not added.\n");
}
else
{
dtvcc->current_packet[dtvcc->current_packet_length++] = data[i + 2];
dtvcc->current_packet[dtvcc->current_packet_length++] = data[i + 3];
int len = dtvcc->current_packet[0] & 0x3F; // 6 least significants bits
if (len == 0) // This is well defined in EIA-708; no magic.
len = 128;
else
len = len * 2;
// Note that len here is the length including the header
if (dtvcc->current_packet_length >= len)
ccx_dtvcc_process_current_packet(dtvcc, len);
}
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_process_data: "
"Warning: Legal packet size exceeded (1), data not added.\n");
}
break;
case 3:
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_process_data: DTVCC Channel Packet Start\n");
if (cc_valid)
else
{
if (dtvcc->current_packet_length > CCX_DTVCC_MAX_PACKET_LENGTH - 1)
{
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_process_data: "
"Warning: Legal packet size exceeded (2), data not added.\n");
}
dtvcc->current_packet[dtvcc->current_packet_length++] = data[2];
dtvcc->current_packet[dtvcc->current_packet_length++] = data[3];
int len = dtvcc->current_packet[0] & 0x3F; // 6 least significants bits
if (len == 0) // This is well defined in EIA-708; no magic.
len = 128;
else
{
dtvcc->current_packet[dtvcc->current_packet_length++] = data[i + 2];
dtvcc->current_packet[dtvcc->current_packet_length++] = data[i + 3];
dtvcc->is_current_packet_header_parsed = 1;
}
len = len * 2;
// Note that len here is the length including the header
if (dtvcc->current_packet_length >= len)
dtvcc_process_current_packet(dtvcc, len);
}
break;
default:
ccx_common_logging.fatal_ftn(CCX_COMMON_EXIT_BUG_BUG, "[CEA-708] dtvcc_process_data: "
"shouldn't be here - cc_type: %d\n",
cc_type);
}
}
break;
case 3:
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_process_data: DTVCC Channel Packet Start\n");
if (cc_valid)
{
if (dtvcc->current_packet_length > CCX_DTVCC_MAX_PACKET_LENGTH - 1)
{
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_process_data: "
"Warning: Legal packet size exceeded (2), data not added.\n");
}
else
{
dtvcc->current_packet[dtvcc->current_packet_length++] = data[2];
dtvcc->current_packet[dtvcc->current_packet_length++] = data[3];
dtvcc->is_current_packet_header_parsed = 1;
}
}
break;
default:
ccx_common_logging.fatal_ftn(CCX_COMMON_EXIT_BUG_BUG, "[CEA-708] dtvcc_process_data: "
"shouldn't be here - cc_type: %d\n",
cc_type);
}
}
//--------------------------------------------------------------------------------------
ccx_dtvcc_ctx *ccx_dtvcc_init(struct ccx_decoder_dtvcc_settings *opts)
dtvcc_ctx *dtvcc_init(struct ccx_decoder_dtvcc_settings *opts)
{
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] initializing dtvcc decoder\n");
ccx_dtvcc_ctx *ctx = (ccx_dtvcc_ctx *)malloc(sizeof(ccx_dtvcc_ctx));
dtvcc_ctx *ctx = (dtvcc_ctx *)malloc(sizeof(dtvcc_ctx));
if (!ctx)
{
ccx_common_logging.fatal_ftn(EXIT_NOT_ENOUGH_MEMORY, "[CEA-708] ccx_dtvcc_init");
ccx_common_logging.fatal_ftn(EXIT_NOT_ENOUGH_MEMORY, "[CEA-708] dtvcc_init");
return NULL;
}
@@ -98,7 +92,7 @@ ccx_dtvcc_ctx *ccx_dtvcc_init(struct ccx_decoder_dtvcc_settings *opts)
memcpy(ctx->services_active, opts->services_enabled, CCX_DTVCC_MAX_SERVICES * sizeof(int));
ccx_dtvcc_clear_packet(ctx);
dtvcc_clear_packet(ctx);
ctx->last_sequence = CCX_DTVCC_NO_LAST_SEQUENCE;
@@ -112,35 +106,35 @@ ccx_dtvcc_ctx *ccx_dtvcc_init(struct ccx_decoder_dtvcc_settings *opts)
if (!ctx->services_active[i])
continue;
ccx_dtvcc_service_decoder *decoder = &ctx->decoders[i];
dtvcc_service_decoder *decoder = &ctx->decoders[i];
decoder->cc_count = 0;
decoder->tv = (dtvcc_tv_screen *)malloc(sizeof(dtvcc_tv_screen));
decoder->tv->service_number = i + 1;
decoder->tv->cc_count = 0;
if (!decoder->tv)
ccx_common_logging.fatal_ftn(EXIT_NOT_ENOUGH_MEMORY, "ccx_dtvcc_init");
ccx_common_logging.fatal_ftn(EXIT_NOT_ENOUGH_MEMORY, "dtvcc_init");
for (int j = 0; j < CCX_DTVCC_MAX_WINDOWS; j++)
decoder->windows[j].memory_reserved = 0;
ccx_dtvcc_windows_reset(decoder);
dtvcc_windows_reset(decoder);
}
return ctx;
}
void ccx_dtvcc_free(ccx_dtvcc_ctx **ctx_ptr)
void dtvcc_free(dtvcc_ctx **ctx_ptr)
{
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_free: cleaning up\n");
ccx_dtvcc_ctx *ctx = *ctx_ptr;
dtvcc_ctx *ctx = *ctx_ptr;
for (int i = 0; i < CCX_DTVCC_MAX_SERVICES; i++)
{
if (!ctx->services_active[i])
continue;
ccx_dtvcc_service_decoder *decoder = &ctx->decoders[i];
dtvcc_service_decoder *decoder = &ctx->decoders[i];
for (int j = 0; j < CCX_DTVCC_MAX_WINDOWS; j++)
if (decoder->windows[j].memory_reserved)

View File

@@ -4,11 +4,10 @@
#include "ccx_decoders_708.h"
#include "ccx_common_option.h"
void ccx_dtvcc_process_data(struct lib_cc_decode *ctx,
const unsigned char *data,
int data_length);
void dtvcc_process_data(struct dtvcc_ctx *dtvcc,
const unsigned char *data);
ccx_dtvcc_ctx *ccx_dtvcc_init(ccx_decoder_dtvcc_settings *opts);
void ccx_dtvcc_free(ccx_dtvcc_ctx **);
dtvcc_ctx *dtvcc_init(ccx_decoder_dtvcc_settings *opts);
void dtvcc_free(dtvcc_ctx **);
#endif //CCEXTRACTOR_CCX_DTVCC_H

View File

@@ -764,7 +764,7 @@ static void dinit_output_ctx(struct encoder_ctx *ctx)
if (ctx->dtvcc_extract)
{
for (i = 0; i < CCX_DTVCC_MAX_SERVICES; i++)
ccx_dtvcc_writer_cleanup(&ctx->dtvcc_writers[i]);
dtvcc_writer_cleanup(&ctx->dtvcc_writers[i]);
}
}
@@ -796,7 +796,7 @@ static int init_output_ctx(struct encoder_ctx *ctx, struct encoder_cfg *cfg)
ctx->ucla = cfg->ucla;
ctx->force_dropframe = cfg->force_dropframe;
if (ctx->generates_file && cfg->cc_to_stdout == CCX_FALSE && cfg->send_to_srv == CCX_FALSE)
if (ctx->generates_file && cfg->cc_to_stdout == CCX_FALSE && cfg->send_to_srv == CCX_FALSE && cfg->extract_only_708 == CCX_FALSE)
{
if (cfg->output_filename != NULL)
{
@@ -869,6 +869,10 @@ static int init_output_ctx(struct encoder_ctx *ctx, struct encoder_cfg *cfg)
if (!cfg->services_enabled[i])
{
ctx->dtvcc_writers[i].fd = -1;
#ifndef DISABLE_RUST
ctx->dtvcc_writers[i].fhandle = NULL;
ctx->dtvcc_writers[i].charset = NULL;
#endif
ctx->dtvcc_writers[i].filename = NULL;
ctx->dtvcc_writers[i].cd = (iconv_t)-1;
continue;
@@ -877,6 +881,10 @@ static int init_output_ctx(struct encoder_ctx *ctx, struct encoder_cfg *cfg)
if (cfg->cc_to_stdout)
{
ctx->dtvcc_writers[i].fd = STDOUT_FILENO;
#ifndef DISABLE_RUST
ctx->dtvcc_writers[i].fhandle = NULL;
ctx->dtvcc_writers[i].charset = NULL;
#endif
ctx->dtvcc_writers[i].filename = NULL;
ctx->dtvcc_writers[i].cd = (iconv_t)-1;
}
@@ -888,8 +896,8 @@ static int init_output_ctx(struct encoder_ctx *ctx, struct encoder_cfg *cfg)
else
basefilename = get_basename(ctx->first_input_file);
ccx_dtvcc_writer_init(&ctx->dtvcc_writers[i], basefilename,
ctx->program_number, i + 1, cfg->write_format, cfg);
dtvcc_writer_init(&ctx->dtvcc_writers[i], basefilename,
ctx->program_number, i + 1, cfg->write_format, cfg);
free(basefilename);
}
}
@@ -1096,11 +1104,6 @@ int encode_sub(struct encoder_ctx *context, struct cc_subtitle *sub)
return wrote_something;
}
sub->start_time += context->subs_delay;
sub->end_time += context->subs_delay;
if (sub->start_time < 0)
return 0;
// Write subtitles as they come
switch (sub->type)
{
@@ -1117,6 +1120,12 @@ int encode_sub(struct encoder_ctx *context, struct cc_subtitle *sub)
data->end_time += context->subs_delay;
data->start_time += context->subs_delay;
// After adding delay, if start/end time is lower than 0, then continue with the next subtitle
if (data->start_time < 0 || data->end_time <= 0)
{
continue;
}
if (data->format == SFORMAT_XDS)
{
xds_write_transcript_line_prefix(context, out, data->start_time, data->end_time, data->cur_xds_packet_class);

View File

@@ -2,7 +2,7 @@
#define _CC_ENCODER_COMMON_H
#ifdef WIN32
#include "..\\win_iconv\\iconv.h"
#include "..\\thirdparty\\win_iconv\\iconv.h"
#else
#include "iconv.h"
#endif
@@ -21,12 +21,18 @@ if (ctx->buffer == NULL) { fatal(EXIT_NOT_ENOUGH_MEMORY, "Not enough memory for
#define ROWS 15
#define COLUMNS 32
typedef struct ccx_dtvcc_writer_ctx
typedef struct dtvcc_writer_ctx
{
int fd;
#ifndef DISABLE_RUST
// File handle used to work with files on windows
void *fhandle;
// Charset of the subtitle
char *charset;
#endif
char *filename;
iconv_t cd;
} ccx_dtvcc_writer_ctx;
} dtvcc_writer_ctx;
typedef struct ccx_sbs_utf8_character
{
@@ -106,7 +112,7 @@ struct encoder_ctx
int extract;
int dtvcc_extract; // 1 or 0 depending if we have to handle dtvcc
ccx_dtvcc_writer_ctx dtvcc_writers[CCX_DTVCC_MAX_SERVICES];
dtvcc_writer_ctx dtvcc_writers[CCX_DTVCC_MAX_SERVICES];
/* Timing related variables*/
/* start time of previous sub */

View File

@@ -1690,17 +1690,30 @@ void dvbsub_handle_display_segment(struct encoder_ctx *enc_ctx,
{
sub->prev->end_time = sub->prev->start_time + sub->prev->time_out;
}
encode_sub(enc_ctx->prev, sub->prev); //we encode it
int timeok = 1;
if (dec_ctx->extraction_start.set &&
sub->prev->start_time < dec_ctx->extraction_start.time_in_ms)
timeok = 0;
if (dec_ctx->extraction_end.set &&
sub->prev->end_time > dec_ctx->extraction_end.time_in_ms)
{
timeok = 0;
dec_ctx->processed_enough = 1;
}
if (timeok)
{
encode_sub(enc_ctx->prev, sub->prev); //we encode it
enc_ctx->last_string = enc_ctx->prev->last_string; // Update last recognized string (used in Matroska)
enc_ctx->prev->last_string = NULL;
enc_ctx->last_string = enc_ctx->prev->last_string; // Update last recognized string (used in Matroska)
enc_ctx->prev->last_string = NULL;
enc_ctx->srt_counter = enc_ctx->prev->srt_counter; //for dvb subs we need to update the current srt counter because we always encode the previous subtitle (and the counter is increased for the previous context)
enc_ctx->prev_start = enc_ctx->prev->prev_start;
sub->prev->got_output = 0;
if (enc_ctx->write_format == CCX_OF_WEBVTT)
{ // we already wrote header, but since we encoded last sub, we must prevent multiple headers in future
enc_ctx->wrote_webvtt_header = 1;
enc_ctx->srt_counter = enc_ctx->prev->srt_counter; //for dvb subs we need to update the current srt counter because we always encode the previous subtitle (and the counter is increased for the previous context)
enc_ctx->prev_start = enc_ctx->prev->prev_start;
sub->prev->got_output = 0;
if (enc_ctx->write_format == CCX_OF_WEBVTT)
{ // we already wrote header, but since we encoded last sub, we must prevent multiple headers in future
enc_ctx->wrote_webvtt_header = 1;
}
}
}
/* copy previous encoder context*/

View File

@@ -1,7 +1,7 @@
#ifndef CCX_CCEXTRACTOR_H
#define CCX_CCEXTRACTOR_H
#define VERSION "0.89"
#define VERSION "0.94"
// Load common includes and constants for library usage
#include "ccx_common_platform.h"

View File

@@ -68,40 +68,40 @@ struct list_head {
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *new,
static inline void __list_add(struct list_head *elem,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
next->prev = elem;
elem->next = next;
elem->prev = prev;
prev->next = elem;
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @elem: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new, struct list_head *head)
static inline void list_add(struct list_head *elem, struct list_head *head)
{
__list_add(new, head, head->next);
__list_add(elem, head, head->next);
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @elem: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *new, struct list_head *head)
static inline void list_add_tail(struct list_head *elem, struct list_head *head)
{
__list_add(new, head->prev, head);
__list_add(elem, head->prev, head);
}

View File

@@ -395,8 +395,7 @@ static int process_clcp(struct lib_ccx_ctx *ctx, struct encoder_ctx *enc_ctx,
}
// WARN: otherwise cea-708 will not work
dec_ctx->dtvcc->encoder = (void *)enc_ctx;
// TODO: is it really always 4-bytes long?
ccx_dtvcc_process_data(dec_ctx, (unsigned char *)temp, 4);
dtvcc_process_data(dec_ctx->dtvcc, (unsigned char *)temp);
cb_708++;
}
if (ctx->write_format == CCX_OF_MCC)
@@ -697,9 +696,22 @@ int processmp4(struct lib_ccx_ctx *ctx, struct ccx_s_mp4Cfg *cfg, char *file)
&dec_sub, &mp4_ret, subtype,
data, sample->dataLength);
break;
case MEDIA_TYPE(GF_ISOM_MEDIA_TEXT, GF_ISOM_SUBTYPE_TEXT): // text:text
{
static int unsupported_reported = 0;
if (!unsupported_reported)
{
mprint("\ntext:text not yet supported, see\n");
mprint("https://developer.apple.com/library/mac/documentation/quicktime/qtff/QTFFChap3/qtff3.html\n");
mprint("If you want to work on a PR.\n");
unsupported_reported = 1;
}
break;
}
default:
// See https://gpac.wp.imt.fr/2014/09/04/subtitling-with-gpac/ for more possible types
mprint("\nUnsupported track type %c%c%c%c:%c%c%c%c! Please report.\n",
mprint("\nUnsupported track type \"%c%c%c%c:%c%c%c%c\". Please report.\n",
(unsigned char)(type >> 24 % 0x100), (unsigned char)((type >> 16) % 0x100),
(unsigned char)((type >> 8) % 0x100), (unsigned char)(type % 0x100),
(unsigned char)(subtype >> 24 % 0x100), (unsigned char)((subtype >> 16) % 0x100),

View File

@@ -35,6 +35,10 @@
#define DEFAULT_FONT_PATH_ITALICS "/usr/share/fonts/truetype/noto/NotoSans-Italic.ttf"
#endif
#ifndef DISABLE_RUST
extern void ccxr_init_logger();
#endif
static int inputfile_capacity = 0;
size_t remove_trailing_whitespace(char *line)
@@ -597,7 +601,6 @@ void print_usage(void)
mprint(" -bom: Append a BOM (Byte Order Mark) to output files.\n");
mprint(" Note that most text processing tools in linux will not\n");
mprint(" like BOM.\n");
mprint(" This is the default in Windows builds.\n");
mprint(" -nobom: Do not append a BOM (Byte Order Mark) to output\n");
mprint(" files. Note that this may break files when using\n");
mprint(" Windows. This is the default in non-Windows builds.\n");
@@ -1024,6 +1027,11 @@ void version(char *location)
mprint(" Version: %s\n", VERSION);
mprint(" Git commit: %s\n", GIT_COMMIT);
mprint(" Compilation date: %s\n", COMPILE_DATE);
#ifndef DISABLE_RUST
mprint(" CEA-708 decoder: Rust\n");
#else
mprint(" CEA-708 decoder: C\n");
#endif
mprint(" File SHA256: %s\n", hash);
mprint("Libraries used by CCExtractor\n");
@@ -1832,6 +1840,7 @@ int parse_parameters(struct ccx_s_options *opt, int argc, char *argv[])
}
if (strcmp(argv[i], "-12") == 0)
{
opt->is_608_enabled = 1;
opt->extract = 12;
continue;
}
@@ -2082,11 +2091,13 @@ int parse_parameters(struct ccx_s_options *opt, int argc, char *argv[])
}
if (strcmp(argv[i], "-1") == 0)
{
opt->is_608_enabled = 1;
opt->extract = 1;
continue;
}
if (strcmp(argv[i], "-2") == 0)
{
opt->is_608_enabled = 1;
opt->extract = 2;
continue;
}
@@ -2179,6 +2190,9 @@ int parse_parameters(struct ccx_s_options *opt, int argc, char *argv[])
if (strcmp(argv[i], "-708") == 0)
{
opt->debug_mask |= CCX_DMT_708;
#ifndef DISABLE_RUST
ccxr_init_logger();
#endif
continue;
}
if (strcmp(argv[i], "-goppts") == 0)
@@ -2329,6 +2343,7 @@ int parse_parameters(struct ccx_s_options *opt, int argc, char *argv[])
{
if (i < argc - 1)
{
opt->is_708_enabled = 1;
i++;
parse_708_services(opt, argv[i]);
continue;
@@ -2961,6 +2976,24 @@ int parse_parameters(struct ccx_s_options *opt, int argc, char *argv[])
{
opt->enc_cfg.output_filename = NULL;
}
if (!opt->is_608_enabled && !opt->is_708_enabled)
{
// If nothing is selected then extract both 608 and 708 subs
// 608 field 1 is enabled by default
// Enable 708 subs extraction
parse_708_services(opt, "all");
}
else if (!opt->is_608_enabled && opt->is_708_enabled)
{
// Extract only 708 subs
// 608 field 1 is enabled by default, disable it
opt->extract = 0;
opt->enc_cfg.extract_only_708 = 1;
}
#ifdef WITH_LIBCURL
opt->enc_cfg.curlposturl = opt->curlposturl;
#endif

View File

@@ -4,7 +4,7 @@
#include "utility.h"
#include <stdbool.h>
#ifdef WIN32
#include "..\\win_iconv\\iconv.h"
#include "..\\thirdparty\\win_iconv\\iconv.h"
#else
#include "iconv.h"
#endif

41
src/rust/CMakeLists.txt Normal file
View File

@@ -0,0 +1,41 @@
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CARGO_CMD cargo build)
set(TARGET_DIR "debug")
else ()
set(CARGO_CMD cargo build --release)
set(TARGET_DIR "release")
endif ()
# Check rust version
set(MSRV "1.54.0")
execute_process(COMMAND rustc --version
OUTPUT_VARIABLE Rust_Version)
string(REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" Rust_Version_string ${Rust_Version})
message(STATUS "Detected rustc version ${Rust_Version_string}")
if (Rust_Version_string VERSION_GREATER_EQUAL ${MSRV})
message(STATUS "rustc >= MSRV(${MSRV})")
else()
message(FATAL_ERROR "Minimum supported rust version(MSRV) is ${MSRV}, please upgrade rust")
endif(Rust_Version_string VERSION_GREATER_EQUAL ${MSRV})
if(WIN32)
set(CCX_RUST_SO "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_DIR}/libccx_rust.lib")
message("${CCX_RUST_SO}")
add_custom_target(ccx_rust ALL
COMMENT "Compiling ccx_rust module"
COMMAND set CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR} ${CARGO_CMD}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
set_target_properties(ccx_rust PROPERTIES LOCATION ${CCX_RUST_SO})
else()
set(CCX_RUST_SO "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_DIR}/libccx_rust.a")
add_custom_target(ccx_rust ALL
COMMENT "Compiling ccx_rust module"
COMMAND CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR} ${CARGO_CMD}
COMMAND cp ${CCX_RUST_SO} ${CMAKE_CURRENT_BINARY_DIR}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
set_target_properties(ccx_rust PROPERTIES LOCATION ${CCX_RUST_SO})
endif()
add_test(NAME ccx_rust_test
COMMAND cargo test
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})

354
src/rust/Cargo.lock generated Normal file
View File

@@ -0,0 +1,354 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "aho-corasick"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
[[package]]
name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
dependencies = [
"winapi",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "bindgen"
version = "0.58.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f8523b410d7187a43085e7e064416ea32ded16bd0a4e6fc025e21616d01258f"
dependencies = [
"bitflags",
"cexpr",
"clang-sys",
"clap",
"env_logger",
"lazy_static",
"lazycell",
"log",
"peeking_take_while",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
"which",
]
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "ccx_rust"
version = "0.1.0"
dependencies = [
"bindgen",
"env_logger",
"iconv",
"log",
]
[[package]]
name = "cexpr"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
dependencies = [
"nom",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clang-sys"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "853eda514c284c2287f4bf20ae614f8781f40a81d32ecda6e91449304dfe077c"
dependencies = [
"glob",
"libc",
"libloading",
]
[[package]]
name = "clap"
version = "2.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "dyn_buf"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74c57ab96715773d9cb9789b38eb7cbf04b3c6f5624a9d98f51761603376767c"
[[package]]
name = "env_logger"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3"
dependencies = [
"atty",
"humantime",
"log",
"regex",
"termcolor",
]
[[package]]
name = "glob"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "hermit-abi"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
dependencies = [
"libc",
]
[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "iconv"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07e6a7db0df823ef299ef75b6951975c7a1f9019910b3665614bac4161bab1a9"
dependencies = [
"dyn_buf",
"libc",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
[[package]]
name = "libloading"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a"
dependencies = [
"cfg-if",
"winapi",
]
[[package]]
name = "log"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
]
[[package]]
name = "memchr"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
[[package]]
name = "nom"
version = "5.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
dependencies = [
"memchr",
"version_check",
]
[[package]]
name = "peeking_take_while"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "proc-macro2"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "shlex"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42a568c8f2cd051a4d283bd6eb0343ac214c1b0f1ac19f93e1175b2dee38c73d"
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "termcolor"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
dependencies = [
"winapi-util",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "unicode-width"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "version_check"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
name = "which"
version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
dependencies = [
"libc",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

19
src/rust/Cargo.toml Normal file
View File

@@ -0,0 +1,19 @@
[package]
name = "ccx_rust"
version = "0.1.0"
authors = ["PunitLodha <punitlodha@pm.me>"]
description = "Rust library for CCExtractor"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
crate-type = ["staticlib"]
[dependencies]
log = "0.4.0"
env_logger = "0.8.4"
iconv = "0.1.1"
[build-dependencies]
bindgen = "0.58.1"

46
src/rust/build.rs Normal file
View File

@@ -0,0 +1,46 @@
use std::env;
use std::path::PathBuf;
fn main() {
let mut builder = bindgen::Builder::default()
// The input header we would like to generate
// bindings for.
.header("wrapper.h")
// Tell cargo to invalidate the built crate whenever any of the
// included header files changed.
.parse_callbacks(Box::new(bindgen::CargoCallbacks));
for type_name in ALLOWLIST_TYPES {
builder = builder.allowlist_type(type_name);
}
for fn_name in ALLOWLIST_FUNCTIONS {
builder = builder.allowlist_function(fn_name);
}
for rust_enum in RUSTIFIED_ENUMS {
builder = builder.rustified_enum(rust_enum);
}
let bindings = builder
// Finish the builder and generate the bindings.
.generate()
// Unwrap the Result and panic on failure.
.expect("Unable to generate bindings");
// Write the bindings to the $OUT_DIR/bindings.rs file.
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}
const ALLOWLIST_FUNCTIONS: &[&str] = &[
".*(?i)_?dtvcc_.*",
"get_visible_.*",
"get_fts",
"printdata",
"writercwtdata",
];
const ALLOWLIST_TYPES: &[&str] = &[".*(?i)_?dtvcc_.*", "encoder_ctx", "lib_cc_decode"];
const RUSTIFIED_ENUMS: &[&str] = &["dtvcc_(window|pen)_.*", "ccx_output_format"];

View File

@@ -0,0 +1,186 @@
//! Different code sets as defined in CEA-708-E
//!
//! Refer section 7.1 CEA-708-E.
//! Different code sets are:
//!
//! | Name | Description | Space |
//! | --- | --- | --- |
//! | C0 | Miscellaneous Control Codes | 0x00 to 0x1F |
//! | C2 | Extended Control Code Set 1 | 0x00 to 0x1F |
//! | G0 | ASCII Printable Characters | 0x20 to 0x7F |
//! | G2 | Extended Miscellaneous Characters | 0x20 to 0x7F |
//! | C1 | Captioning Command Control Codes | 0x80 to 0x9F |
//! | C3 | Extended Control Code Set 2 | 0x80 to 0x9F |
//! | G1 | ISO 8859-1 Latin-1 Character Set | 0xA0 to 0xFF |
//! | G3 | Future Expansion | 0xA0 to 0xFF |
/// Different C0 commands
#[allow(clippy::upper_case_acronyms)]
#[derive(Debug)]
pub enum C0CodeSet {
NUL,
ETX,
BS,
FF,
CR,
HCR,
EXT1,
P16,
RESERVED,
}
impl C0CodeSet {
/// Create a new command from the byte value
pub fn new(data: u8) -> Self {
match data {
0 => C0CodeSet::NUL,
0x3 => C0CodeSet::ETX,
0x8 => C0CodeSet::BS,
0xC => C0CodeSet::FF,
0xD => C0CodeSet::CR,
0xE => C0CodeSet::HCR,
0x10 => C0CodeSet::EXT1,
0x18 => C0CodeSet::P16,
_ => C0CodeSet::RESERVED,
}
}
}
/// C0 command with its length
pub struct C0Command {
pub command: C0CodeSet,
pub length: u8,
}
impl C0Command {
/// Create a new command from the byte value
pub fn new(data: u8) -> Self {
let command = C0CodeSet::new(data);
// lengths are defined in CEA-708-E section 7.1.4
let length = match data {
0..=0xF => 1,
0x10..=0x17 => 2,
0x18..=0x1F => 3,
// Unreachable arm as C0 code set is only from 0 - 0x1F
_ => 1,
};
C0Command { command, length }
}
}
/// Different C1 commands
#[allow(clippy::upper_case_acronyms)]
#[derive(Debug)]
pub enum C1CodeSet {
CW0,
CW1,
CW2,
CW3,
CW4,
CW5,
CW6,
CW7,
CLW,
DSW,
HDW,
TGW,
DLW,
DLY,
DLC,
RST,
SPA,
SPC,
SPL,
SWA,
DF0,
DF1,
DF2,
DF3,
DF4,
DF5,
DF6,
DF7,
RESERVED,
}
/// C1 command with its length
pub struct C1Command {
pub command: C1CodeSet,
pub length: u8,
pub name: String,
}
impl C1Command {
/// Create a new command from the byte value
pub fn new(data: u8) -> Self {
let (command, name, length) = match data {
0x80 => (C1CodeSet::CW0, "SetCurrentWindow0", 1),
0x81 => (C1CodeSet::CW1, "SetCurrentWindow1", 1),
0x82 => (C1CodeSet::CW2, "SetCurrentWindow2", 1),
0x83 => (C1CodeSet::CW3, "SetCurrentWindow3", 1),
0x84 => (C1CodeSet::CW4, "SetCurrentWindow4", 1),
0x85 => (C1CodeSet::CW5, "SetCurrentWindow5", 1),
0x86 => (C1CodeSet::CW6, "SetCurrentWindow6", 1),
0x87 => (C1CodeSet::CW7, "SetCurrentWindow7", 1),
0x88 => (C1CodeSet::CLW, "ClearWindows", 2),
0x89 => (C1CodeSet::DSW, "DisplayWindows", 2),
0x8A => (C1CodeSet::HDW, "HideWindows", 2),
0x8B => (C1CodeSet::TGW, "ToggleWindows", 2),
0x8C => (C1CodeSet::DLW, "DeleteWindows", 2),
0x8D => (C1CodeSet::DLY, "Delay", 2),
0x8E => (C1CodeSet::DLC, "DelayCancel", 1),
0x8F => (C1CodeSet::RST, "Reset", 1),
0x90 => (C1CodeSet::SPA, "SetPenAttributes", 3),
0x91 => (C1CodeSet::SPC, "SetPenColor", 4),
0x92 => (C1CodeSet::SPL, "SetPenLocation", 3),
0x97 => (C1CodeSet::SWA, "SetWindowAttributes", 5),
0x98 => (C1CodeSet::DF0, "DefineWindow0", 7),
0x99 => (C1CodeSet::DF1, "DefineWindow1", 7),
0x9A => (C1CodeSet::DF2, "DefineWindow2", 7),
0x9B => (C1CodeSet::DF3, "DefineWindow3", 7),
0x9C => (C1CodeSet::DF4, "DefineWindow4", 7),
0x9D => (C1CodeSet::DF5, "DefineWindow5", 7),
0x9E => (C1CodeSet::DF6, "DefineWindow6", 7),
0x9F => (C1CodeSet::DF7, "DefineWindow7", 7),
_ => (C1CodeSet::RESERVED, "Reserved", 1),
};
let name = name.to_owned();
Self {
command,
length,
name,
}
}
}
/// Handle C2 - Code Set - Extended Control Code Set 1
pub fn handle_C2(code: u8) -> u8 {
match code {
// ... Single-byte control bytes (0 additional bytes)
0..=0x07 => 1,
// ..two-byte control codes (1 additional byte)
0x08..=0x0F => 2,
// ..three-byte control codes (2 additional bytes)
0x10..=0x17 => 3,
// 18-1F => four-byte control codes (3 additional bytes)
_ => 4,
}
}
/// Handle C3 - Code Set - Extended Control Code Set 2
pub fn handle_C3(code: u8, next_code: u8) -> u8 {
match code {
// Five-byte control bytes (4 additional bytes)
0x80..=0x87 => 5,
// Six-byte control codes (5 additional byte)
0x88..=0x8F => 6,
// 90-9F variable length commands
// Refer Section 7.1.11.2
_ => {
// next code is the header which specifies additional bytes
let length = (next_code & 0x3F) + 1;
// + 1 for current code
length + 1
}
}
}

221
src/rust/src/decoder/mod.rs Normal file
View File

@@ -0,0 +1,221 @@
//! CEA 708 decoder
//!
//! Provides a CEA 708 decoder as defined by ANSI/CTA-708-E R-2018
mod commands;
mod output;
mod service_decoder;
mod timing;
mod tv_screen;
mod window;
use crate::{bindings::*, utils::is_true};
use log::{debug, warn};
const CCX_DTVCC_MAX_PACKET_LENGTH: u8 = 128;
const CCX_DTVCC_NO_LAST_SEQUENCE: i32 = -1;
const CCX_DTVCC_SCREENGRID_ROWS: u8 = 75;
const CCX_DTVCC_SCREENGRID_COLUMNS: u8 = 210;
const CCX_DTVCC_MAX_ROWS: u8 = 15;
const CCX_DTVCC_MAX_COLUMNS: u8 = 32 * 2;
/// Context required for processing 708 data
pub struct Dtvcc<'a> {
pub is_active: bool,
pub active_services_count: u8,
pub services_active: Vec<i32>,
pub report_enabled: bool,
pub report: &'a mut ccx_decoder_dtvcc_report,
pub decoders: Vec<&'a mut dtvcc_service_decoder>,
pub packet: Vec<u8>,
pub packet_length: u8,
pub is_header_parsed: bool,
pub last_sequence: i32,
pub encoder: &'a mut encoder_ctx,
pub no_rollup: bool,
pub timing: &'a mut ccx_common_timing_ctx,
}
impl<'a> Dtvcc<'a> {
/// Create a new dtvcc context
pub fn new(ctx: &'a mut dtvcc_ctx) -> Self {
let report = unsafe { &mut *ctx.report };
let encoder = unsafe { &mut *(ctx.encoder as *mut encoder_ctx) };
let timing = unsafe { &mut *ctx.timing };
Self {
is_active: is_true(ctx.is_active),
active_services_count: ctx.active_services_count as u8,
services_active: ctx.services_active.iter().copied().collect(),
report_enabled: is_true(ctx.report_enabled),
report,
decoders: ctx.decoders.iter_mut().collect(),
packet: ctx.current_packet.to_vec(),
packet_length: ctx.current_packet_length as u8,
is_header_parsed: is_true(ctx.is_current_packet_header_parsed),
last_sequence: ctx.last_sequence,
encoder,
no_rollup: is_true(ctx.no_rollup),
timing,
}
}
/// Process cc data and add it to the dtvcc packet
pub fn process_cc_data(&mut self, cc_valid: u8, cc_type: u8, data1: u8, data2: u8) {
if !self.is_active && !self.report_enabled {
return;
}
match cc_type {
// type 0 and 1 are for CEA 608 data and are handled before calling this function
// valid types for CEA 708 data are only 2 and 3
2 => {
debug!("dtvcc_process_data: DTVCC Channel Packet Data");
if cc_valid == 1 && self.is_header_parsed {
if self.packet_length > 253 {
warn!("dtvcc_process_data: Warning: Legal packet size exceeded (1), data not added.");
} else {
self.add_data_to_packet(data1, data2);
let mut max_len = self.packet[0] & 0x3F;
if max_len == 0 {
// This is well defined in EIA-708; no magic.
max_len = 128;
} else {
max_len *= 2;
}
// If packet is complete then process the packet
if self.packet_length >= max_len {
self.process_current_packet(max_len);
}
}
}
}
3 => {
debug!("dtvcc_process_data: DTVCC Channel Packet Start");
if cc_valid == 1 {
if self.packet_length > (CCX_DTVCC_MAX_PACKET_LENGTH - 1) {
warn!("dtvcc_process_data: Warning: Legal packet size exceeded (2), data not added.");
} else {
self.add_data_to_packet(data1, data2);
self.is_header_parsed = true;
}
}
}
_ => warn!(
"dtvcc_process_data: shouldn't be here - cc_type: {}",
cc_type
),
}
}
/// Add data to the packet
pub fn add_data_to_packet(&mut self, data1: u8, data2: u8) {
self.packet[self.packet_length as usize] = data1;
self.packet_length += 1;
self.packet[self.packet_length as usize] = data2;
self.packet_length += 1;
}
/// Process current packet into service blocks
pub fn process_current_packet(&mut self, len: u8) {
let seq = (self.packet[0] & 0xC0) >> 6;
debug!(
"dtvcc_process_current_packet: Sequence: {}, packet length: {}",
seq, len
);
if self.packet_length == 0 {
return;
}
// Check if current sequence is correct
// Sequence number is a 2 bit rolling sequence from (0-3)
if self.last_sequence != CCX_DTVCC_NO_LAST_SEQUENCE
&& (self.last_sequence + 1) % 4 != seq as i32
{
warn!("dtvcc_process_current_packet: Unexpected sequence number, it is {} but should be {}", seq, (self.last_sequence +1) % 4);
}
self.last_sequence = seq as i32;
let mut pos: u8 = 1;
while pos < len {
let mut service_number = (self.packet[pos as usize] & 0xE0) >> 5; // 3 more significant bits
let block_length = self.packet[pos as usize] & 0x1F; // 5 less significant bits
debug!("dtvcc_process_current_packet: Standard header Service number: {}, Block length: {}", service_number, block_length);
if service_number == 7 {
// There is an extended header
// CEA-708-E 6.2.2 Extended Service Block Header
pos += 1;
service_number = self.packet[pos as usize] & 0x3F; // 6 more significant bits
if service_number > 7 {
warn!("dtvcc_process_current_packet: Illegal service number in extended header: {}", service_number);
}
}
pos += 1;
if service_number == 0 && block_length != 0 {
// Illegal, but specs say what to do...
pos = len; // Move to end
break;
}
if block_length != 0 {
self.report.services[service_number as usize] = 1;
}
if service_number > 0 && is_true(self.services_active[(service_number - 1) as usize]) {
let decoder = &mut self.decoders[(service_number - 1) as usize];
decoder.process_service_block(
&self.packet[pos as usize..(pos + block_length) as usize],
self.encoder,
self.timing,
self.no_rollup,
);
}
pos += block_length // Skip data
}
self.clear_packet();
if len < 128 && self.packet[pos as usize] != 0 {
// Null header is mandatory if there is room
warn!("dtvcc_process_current_packet: Warning: Null header expected but not found.");
}
}
/// Clear current packet
pub fn clear_packet(&mut self) {
self.packet_length = 0;
self.is_header_parsed = false;
self.packet.iter_mut().for_each(|x| *x = 0);
}
}
/// A single character symbol
///
/// sym stores the symbol
/// init is used to know if the symbol is initialized
impl dtvcc_symbol {
/// Create a new symbol
pub fn new(sym: u16) -> Self {
Self { init: 1, sym }
}
/// Create a new 16 bit symbol
pub fn new_16(data1: u8, data2: u8) -> Self {
let sym = (data1 as u16) << 8 | data2 as u16;
Self { init: 1, sym }
}
/// Check if symbol is initialized
pub fn is_set(&self) -> bool {
is_true(self.init)
}
}
impl Default for dtvcc_symbol {
/// Create a blank uninitialized symbol
fn default() -> Self {
Self { sym: 0, init: 0 }
}
}

View File

@@ -0,0 +1,112 @@
//! Utilty functions to write captions
#[cfg(unix)]
use std::os::unix::prelude::{FromRawFd, IntoRawFd};
#[cfg(windows)]
use std::os::windows::io::{FromRawHandle, IntoRawHandle};
use std::{fs::File, io::Write};
use crate::{bindings::*, utils::is_true};
use log::{debug, warn};
// Context for writing subtitles to file
pub struct Writer<'a> {
pub cea_708_counter: &'a mut u32,
pub subs_delay: LLONG,
pub crlf: String,
pub write_format: ccx_output_format,
pub writer_ctx: &'a mut dtvcc_writer_ctx,
pub no_font_color: bool,
pub transcript_settings: &'a ccx_encoders_transcript_format,
pub no_bom: i32,
}
impl<'a> Writer<'a> {
/// Create a new writer context
pub fn new(
cea_708_counter: &'a mut u32,
subs_delay: LLONG,
write_format: ccx_output_format,
writer_ctx: &'a mut dtvcc_writer_ctx,
no_font_color: i32,
transcript_settings: &'a ccx_encoders_transcript_format,
no_bom: i32,
) -> Self {
Self {
cea_708_counter,
subs_delay,
crlf: "\r\n".to_owned(),
write_format,
writer_ctx,
no_font_color: is_true(no_font_color),
transcript_settings,
no_bom,
}
}
/// Write subtitles to the file
///
/// File must already exist
/// On Unix Platforms, uses the raw fd from context to access the file
/// On Windows Platforms, uses the raw handle from context to access the file
pub fn write_to_file(&mut self, buf: &[u8]) -> Result<(), String> {
#[cfg(unix)]
{
let mut file = unsafe { File::from_raw_fd(self.writer_ctx.fd) };
file.write_all(buf).map_err(|err| err.to_string())?;
self.writer_ctx.fd = file.into_raw_fd();
}
#[cfg(windows)]
{
let mut file = unsafe { File::from_raw_handle(self.writer_ctx.fhandle) };
file.write_all(buf).map_err(|err| err.to_string())?;
self.writer_ctx.fhandle = file.into_raw_handle();
}
Ok(())
}
/// Finish writing up any remaining parts
pub fn write_done(&mut self) {
if self.write_format == ccx_output_format::CCX_OF_SAMI {
if let Err(err) = self.write_sami_footer() {
warn!("{}", err);
}
} else {
debug!("dtvcc_write_done: no handling required");
}
}
/// Writes the footer according to the SAMI format
pub fn write_sami_footer(&mut self) -> Result<(), String> {
self.write_to_file(b"</body></sami>")?;
Ok(())
}
}
/// Write the symbol to the provided buffer
///
/// If symbol is 8-bit, then it's written to the buffer
/// If symbol is 16-bit, then two 8-bit symbols are written to the buffer
pub fn write_char(sym: &dtvcc_symbol, buf: &mut Vec<u8>) {
if sym.sym >> 8 != 0 {
buf.push((sym.sym >> 8) as u8);
buf.push((sym.sym & 0xff) as u8);
} else {
buf.push(sym.sym as u8);
}
}
/// Convert from CEA-708 color representation to hex code
///
/// Two bits are specified for each red, green, and blue color value which defines the
/// intensity of each individual color component.
///
/// Refer section 8.8 CEA-708-E
pub fn color_to_hex(color: u8) -> (u8, u8, u8) {
let red = color >> 4;
let green = (color >> 2) & 0x3;
let blue = color & 0x3;
debug!(
"Color: {} [{:06x}] {} {} {}",
color, color, red, green, blue
);
(red, green, blue)
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,49 @@
//! Utilty functions to get timing for captions
use crate::{bindings::*, cb_708, cb_field1, cb_field2};
use log::{debug, error};
impl ccx_common_timing_ctx {
/// Return the current FTS
pub fn get_fts(&self, current_field: u8) -> LLONG {
unsafe {
match current_field {
1 => self.fts_now + self.fts_global + cb_field1 as i64 * 1001 / 30,
2 => self.fts_now + self.fts_global + cb_field2 as i64 * 1001 / 30,
3 => self.fts_now + self.fts_global + cb_708 as i64 * 1001 / 30,
_ => {
error!("get_fts: Unknown field");
0
}
}
}
}
/// Returns the current FTS and saves it so it can be used by [get_visible_start][Self::get_visible_start()]
pub fn get_visible_end(&mut self, current_field: u8) -> LLONG {
let fts = self.get_fts(current_field);
if fts > self.minimum_fts {
self.minimum_fts = fts;
}
debug!("Visible End time={}", get_time_str(fts));
fts
}
/// Returns a FTS that is guaranteed to be at least 1 ms later than the end of the previous screen, so that there's no timing overlap
pub fn get_visible_start(self, current_field: u8) -> LLONG {
let mut fts = self.get_fts(current_field);
if fts <= self.minimum_fts {
fts = self.minimum_fts + 1;
}
debug!("Visible Start time={}", get_time_str(fts));
fts
}
}
/// Returns a hh:mm:ss,ms string of time
pub fn get_time_str(time: LLONG) -> String {
let hh = time / 1000 / 60 / 60;
let mm = time / 1000 / 60 - 60 * hh;
let ss = time / 1000 - 60 * (mm + 60 * hh);
let ms = time - 1000 * (ss + 60 * (mm + 60 * hh));
format!("{:02}:{:02}:{:02},{:03}", hh, mm, ss, ms)
}

View File

@@ -0,0 +1,477 @@
//! TV screen to be displayed
//!
//! TV screen contains the captions to be displayed.
//! Captions are added to TV screen from a window when any of DSW, HDW, TGW, DLW or CR commands are received
#[cfg(unix)]
use std::os::unix::prelude::IntoRawFd;
#[cfg(windows)]
use std::os::windows::io::IntoRawHandle;
use std::{ffi::CStr, fs::File};
use super::output::{color_to_hex, write_char, Writer};
use super::timing::get_time_str;
use super::{CCX_DTVCC_SCREENGRID_COLUMNS, CCX_DTVCC_SCREENGRID_ROWS};
use crate::{
bindings::*,
utils::{is_false, is_true},
};
use log::{debug, warn};
impl dtvcc_tv_screen {
/// Clear all text from TV screen
pub fn clear(&mut self) {
for row in 0..CCX_DTVCC_SCREENGRID_ROWS as usize {
self.chars[row].fill(dtvcc_symbol::default());
}
self.time_ms_hide = -1;
self.time_ms_show = -1;
}
/// Update TV screen show time
pub fn update_time_show(&mut self, time: LLONG) {
let prev_time_str = get_time_str(self.time_ms_show);
let curr_time_str = get_time_str(time);
debug!("Screen show time: {} -> {}", prev_time_str, curr_time_str);
if self.time_ms_show == -1 || self.time_ms_show > time {
self.time_ms_show = time;
}
}
/// Update TV screen hide time
pub fn update_time_hide(&mut self, time: LLONG) {
let prev_time_str = get_time_str(self.time_ms_hide);
let curr_time_str = get_time_str(time);
debug!("Screen hide time: {} -> {}", prev_time_str, curr_time_str);
if self.time_ms_hide == -1 || self.time_ms_hide < time {
self.time_ms_hide = time;
}
}
/// Write captions to the output file
///
/// Opens a new file when called for the first time.
/// Uses the already open file on subsequent calls.
pub fn writer_output(&self, writer: &mut Writer) -> Result<(), String> {
debug!(
"dtvcc_writer_output: writing... [{:?}][{}]",
unsafe { CStr::from_ptr(writer.writer_ctx.filename) },
writer.writer_ctx.fd
);
#[cfg(unix)]
if writer.writer_ctx.filename.is_null() && writer.writer_ctx.fd < 0 {
return Err("Filename missing".to_owned());
} else if writer.writer_ctx.fd < 0 {
let filename = unsafe {
CStr::from_ptr(writer.writer_ctx.filename)
.to_str()
.map_err(|err| err.to_string())
}?;
debug!("dtvcc_writer_output: creating {}", filename);
let file = File::create(filename).map_err(|err| err.to_string())?;
writer.writer_ctx.fd = file.into_raw_fd();
if is_false(writer.no_bom) {
let BOM = [0xef, 0xbb, 0xbf];
writer.write_to_file(&BOM)?;
}
}
#[cfg(windows)]
if writer.writer_ctx.filename.is_null() && writer.writer_ctx.fhandle.is_null() {
return Err("Filename missing".to_owned())?;
} else if writer.writer_ctx.fhandle.is_null() {
let filename = unsafe {
CStr::from_ptr(writer.writer_ctx.filename)
.to_str()
.map_err(|err| err.to_string())
}?;
debug!("dtvcc_writer_output: creating {}", filename);
let file = File::create(filename).map_err(|err| err.to_string())?;
writer.writer_ctx.fhandle = file.into_raw_handle();
if is_false(writer.no_bom) {
let BOM = [0xef, 0xbb, 0xbf];
writer.write_to_file(&BOM)?;
}
}
self.write(writer);
Ok(())
}
/// Returns the bounds in which captions are present
pub fn get_write_interval(&self, row_index: usize) -> (usize, usize) {
let mut first = 0;
let mut last = CCX_DTVCC_SCREENGRID_COLUMNS as usize - 1;
for col in 0..CCX_DTVCC_SCREENGRID_COLUMNS as usize {
if self.chars[row_index][col].is_set() {
first = col;
break;
}
}
for col in (0..(CCX_DTVCC_SCREENGRID_COLUMNS as usize - 1)).rev() {
if self.chars[row_index][col].is_set() {
last = col;
break;
}
}
(first, last)
}
/// Write captions according to the output file type
///
/// Calls the respective function for the output file type
pub fn write(&self, writer: &mut Writer) {
let result = match writer.write_format {
ccx_output_format::CCX_OF_SRT => self.write_srt(writer),
ccx_output_format::CCX_OF_SAMI => self.write_sami(writer),
ccx_output_format::CCX_OF_TRANSCRIPT => self.write_transcript(writer),
_ => {
self.write_debug();
Err("Unsupported write format".to_owned())
}
};
if let Err(err) = result {
warn!("{}", err);
}
}
/// Write all captions from the row to the output file
///
/// If use_colors is 'true' then <font color="xxx"></font> tags are added to the output
pub fn write_row(
&self,
writer: &mut Writer,
row_index: usize,
use_colors: bool,
) -> Result<(), String> {
let mut buf = Vec::new();
let mut pen_color = dtvcc_pen_color::default();
let mut pen_attribs = dtvcc_pen_attribs::default();
let (first, last) = self.get_write_interval(row_index);
debug!("First: {}, Last: {}", first, last);
for i in 0..last + 1 {
if use_colors {
self.change_pen_color(
&pen_color,
writer.no_font_color,
row_index,
i,
false,
&mut buf,
);
}
self.change_pen_attribs(
&pen_attribs,
writer.no_font_color,
row_index,
i,
false,
&mut buf,
);
self.change_pen_attribs(
&pen_attribs,
writer.no_font_color,
row_index,
i,
true,
&mut buf,
);
if use_colors {
self.change_pen_color(
&pen_color,
writer.no_font_color,
row_index,
i,
true,
&mut buf,
)
}
pen_color = self.pen_colors[row_index][i];
pen_attribs = self.pen_attribs[row_index][i];
if i < first {
buf.push(b' ');
} else {
write_char(&self.chars[row_index][i], &mut buf)
}
}
// there can be unclosed tags or colors after the last symbol in a row
if use_colors {
self.change_pen_color(
&pen_color,
writer.no_font_color,
row_index,
CCX_DTVCC_SCREENGRID_COLUMNS as usize,
false,
&mut buf,
)
}
self.change_pen_attribs(
&pen_attribs,
writer.no_font_color,
row_index,
CCX_DTVCC_SCREENGRID_COLUMNS as usize,
false,
&mut buf,
);
// Tags can still be crossed e.g <f><i>text</f></i>, but testing HTML code has shown that they still are handled correctly.
if writer.writer_ctx.cd != (-1_isize) as iconv_t {
if writer.writer_ctx.charset.is_null() {
debug!("Charset: null");
} else {
let charset = unsafe {
CStr::from_ptr(writer.writer_ctx.charset)
.to_str()
.map_err(|err| err.to_string())?
};
debug!("Charset: {}", charset);
let op = iconv::decode(&buf, charset).map_err(|err| err.to_string())?;
writer.write_to_file(op.as_bytes())?;
}
} else {
writer.write_to_file(&buf)?;
}
Ok(())
}
/// Write captions in SRT format
pub fn write_srt(&self, writer: &mut Writer) -> Result<(), String> {
if self.is_screen_empty(writer) {
return Ok(());
}
if self.time_ms_show + writer.subs_delay < 0 {
return Ok(());
}
let time_show = get_time_str(self.time_ms_show);
let time_hide = get_time_str(self.time_ms_hide);
let counter = *writer.cea_708_counter;
let line = format!(
"{}{}{} --> {}{}",
counter, "\r\n", time_show, time_hide, "\r\n"
);
writer.write_to_file(line.as_bytes())?;
for row_index in 0..CCX_DTVCC_SCREENGRID_ROWS as usize {
if !self.is_row_empty(row_index) {
self.write_row(writer, row_index, true)?;
writer.write_to_file(b"\r\n")?;
}
}
writer.write_to_file(b"\r\n")?;
Ok(())
}
/// Write captions in Transcripts format
pub fn write_transcript(&self, writer: &mut Writer) -> Result<(), String> {
if self.is_screen_empty(writer) {
return Ok(());
}
if self.time_ms_show + writer.subs_delay < 0 {
return Ok(());
}
let time_show = get_time_str(self.time_ms_show);
let time_hide = get_time_str(self.time_ms_hide);
for row_index in 0..CCX_DTVCC_SCREENGRID_ROWS as usize {
if !self.is_row_empty(row_index) {
let mut buf = String::new();
if is_true(writer.transcript_settings.showStartTime) {
buf.push_str(&time_show);
buf.push('|');
}
if is_true(writer.transcript_settings.showEndTime) {
buf.push_str(&time_hide);
buf.push('|');
}
if is_true(writer.transcript_settings.showCC) {
buf.push_str("CC1|"); //always CC1 because CEA-708 is field-independent
}
if is_true(writer.transcript_settings.showMode) {
buf.push_str("POP|"); //TODO caption mode(pop, rollup, etc.)
}
writer.write_to_file(buf.as_bytes())?;
self.write_row(writer, row_index, false)?;
writer.write_to_file(b"\r\n")?;
}
}
Ok(())
}
/// Write captions in SAMI format
pub fn write_sami(&self, writer: &mut Writer) -> Result<(), String> {
if self.is_screen_empty(writer) {
return Err("Sami:- Screen is empty".to_owned());
}
if self.time_ms_show + writer.subs_delay < 0 {
return Err(format!(
"Sami:- timing is -ve, {}:{}",
self.time_ms_show, writer.subs_delay
));
}
if self.cc_count == 1 {
self.write_sami_header(writer)?;
}
let buf = format!(
"<sync start={}><p class=\"unknowncc\">\r\n",
self.time_ms_show + writer.subs_delay
);
writer.write_to_file(buf.as_bytes())?;
for row_index in 0..CCX_DTVCC_SCREENGRID_ROWS as usize {
if !self.is_row_empty(row_index) {
self.write_row(writer, row_index, true)?;
writer.write_to_file("<br>\r\n".as_bytes())?;
}
}
let buf = format!(
"<sync start={}><p class=\"unknowncc\">&nbsp;</p></sync>\r\n\r\n",
self.time_ms_hide + writer.subs_delay
);
writer.write_to_file(buf.as_bytes())?;
Ok(())
}
/// Writes the header according to the SAMI format
pub fn write_sami_header(&self, writer: &mut Writer) -> Result<(), String> {
let buf = b"<sami>\r\n\
<head>\r\n\
<style type=\"text/css\">\r\n\
<!--\r\n\
p {margin-left: 16pt; margin-right: 16pt; margin-bottom: 16pt; margin-top: 16pt;\r\n\
text-align: center; font-size: 18pt; font-family: arial; font-weight: bold; color: #f0f0f0;}\r\n\
.unknowncc {Name:Unknown; lang:en-US; SAMIType:CC;}\r\n\
-->\r\n\
</style>\r\n\
</head>\r\n\r\n\
<body>\r\n";
writer.write_to_file(buf)?;
Ok(())
}
/// Write debug messages
///
/// Write all characters,show and hide time as a debug log
pub fn write_debug(&self) {
let time_show = get_time_str(self.time_ms_show);
let time_hide = get_time_str(self.time_ms_hide);
debug!("{} --> {}", time_show, time_hide);
for row_index in 0..CCX_DTVCC_SCREENGRID_ROWS as usize {
if !self.is_row_empty(row_index) {
let mut buf = String::new();
let (first, last) = self.get_write_interval(row_index);
for sym in self.chars[row_index][first..=last].iter() {
buf.push_str(&format!("{:04X},", sym.sym));
}
debug!("{}", buf);
}
}
}
/// Returns `true` if TV screen has no text
///
/// If any text is found then 708 counter is incremented
pub fn is_screen_empty(&self, writer: &mut Writer) -> bool {
for index in 0..CCX_DTVCC_SCREENGRID_ROWS as usize {
if !self.is_row_empty(index) {
// we will write subtitle
*writer.cea_708_counter += 1;
return false;
}
}
true
}
/// Returns `true` if row has no text
pub fn is_row_empty(&self, row_index: usize) -> bool {
for col_index in 0..CCX_DTVCC_SCREENGRID_COLUMNS as usize {
if self.chars[row_index][col_index].is_set() {
return false;
}
}
true
}
/// Add underline(<u>) and italic(<i>) tags according to the pen attributes
///
/// Open specifies if tag is an opening or closing tag
pub fn change_pen_attribs(
&self,
pen_attribs: &dtvcc_pen_attribs,
no_font_color: bool,
row_index: usize,
col_index: usize,
open: bool,
buf: &mut Vec<u8>,
) {
if no_font_color {
return;
}
let new_pen_attribs = if col_index >= CCX_DTVCC_SCREENGRID_COLUMNS as usize {
dtvcc_pen_attribs::default()
} else {
self.pen_attribs[row_index][col_index]
};
if pen_attribs.italic != new_pen_attribs.italic {
if is_true(pen_attribs.italic) && !open {
buf.extend_from_slice(b"</i>");
} else if is_false(pen_attribs.italic) && open {
buf.extend_from_slice(b"<i>");
}
}
if pen_attribs.underline != new_pen_attribs.underline {
if is_true(pen_attribs.underline) && !open {
buf.extend_from_slice(b"</u>");
} else if is_false(pen_attribs.underline) && open {
buf.extend_from_slice(b"<u>");
}
}
}
/// Add font(<font color="xxx">) tag according to the pen color
///
/// Open specifies if tag is an opening or closing tag
pub fn change_pen_color(
&self,
pen_color: &dtvcc_pen_color,
no_font_color: bool,
row_index: usize,
col_index: usize,
open: bool,
buf: &mut Vec<u8>,
) {
if no_font_color {
return;
}
let new_pen_color = if col_index >= CCX_DTVCC_SCREENGRID_COLUMNS as usize {
dtvcc_pen_color::default()
} else {
self.pen_colors[row_index][col_index]
};
if pen_color.fg_color != new_pen_color.fg_color {
if pen_color.fg_color != 0x3F && !open {
// should close older non-white color
buf.extend_from_slice(b"</font>");
} else if new_pen_color.fg_color != 0x3F && open {
debug!("Colors: {}", col_index);
let (mut red, mut green, mut blue) = color_to_hex(new_pen_color.fg_color as u8);
red *= 255 / 3;
green *= 255 / 3;
blue *= 255 / 3;
let font_tag = format!("<font color=\"{:02x}{:02x}{:02x}\">", red, green, blue);
buf.extend_from_slice(font_tag.as_bytes());
}
}
}
}

View File

@@ -0,0 +1,550 @@
//! Caption windows
//!
//! Refer Section 8.4 CEA-708-E
//!
//! All caption text is displayed and manipulated in the context of caption windows. There are 8
//! possible windows per service in which caption providers may write caption text.
//! Each of the eight windows is uniquely addressed by its window ID. Window ID
//! numbers range from 0 to 7.
//!
//! At any time there is a current window to which all subsequent
//! window/pen commands are directed. All caption text is written to the current window
use std::{
alloc::{alloc_zeroed, dealloc, Layout},
intrinsics::copy_nonoverlapping,
};
use super::timing::get_time_str;
use super::{
CCX_DTVCC_MAX_COLUMNS, CCX_DTVCC_MAX_ROWS, CCX_DTVCC_SCREENGRID_COLUMNS,
CCX_DTVCC_SCREENGRID_ROWS,
};
use crate::{bindings::*, utils::is_true};
use log::{debug, error};
impl dtvcc_window {
/// Sets the window style according to the window preset
pub fn set_style(&mut self, preset: WindowPreset) {
let style_id = preset as i32;
let window_style = WindowStyle::new(preset);
self.win_style = style_id;
self.attribs.border_color = window_style.border_color as i32;
self.attribs.border_type = window_style.border_type as i32;
self.attribs.display_effect = window_style.display_effect as i32;
self.attribs.effect_direction = window_style.effect_direction as i32;
self.attribs.effect_speed = window_style.effect_speed as i32;
self.attribs.fill_color = window_style.fill_color as i32;
self.attribs.fill_opacity = window_style.fill_opacity as i32;
self.attribs.justify = window_style.justify as i32;
self.attribs.print_direction = window_style.print_direction as i32;
self.attribs.scroll_direction = window_style.scroll_direction as i32;
self.attribs.word_wrap = window_style.word_wrap as i32;
}
/// Sets the pen style according to the pen preset
pub fn set_pen_style(&mut self, preset: PenPreset) {
let pen_style = PenStyle::new(preset);
let pen = &mut self.pen_attribs_pattern;
pen.pen_size = pen_style.pen_size as i32;
pen.offset = pen_style.offset as i32;
pen.edge_type = pen_style.edge_type as i32;
pen.underline = pen_style.underline as i32;
pen.italic = pen_style.italics as i32;
let pen_color = &mut self.pen_color_pattern;
pen_color.fg_color = pen_style.color.fg_color as i32;
pen_color.fg_opacity = pen_style.color.fg_opacity as i32;
pen_color.bg_color = pen_style.color.bg_color as i32;
pen_color.bg_opacity = pen_style.color.bg_opacity as i32;
pen_color.edge_color = pen_style.color.edge_color as i32;
}
/// Update the show time for the window
pub fn update_time_show(&mut self, timing: &mut ccx_common_timing_ctx) {
self.time_ms_show = timing.get_visible_start(3);
let time = get_time_str(self.time_ms_show);
debug!("[W-{}] show time updated to {}", self.number, time);
}
/// Update the hide time for the window
pub fn update_time_hide(&mut self, timing: &mut ccx_common_timing_ctx) {
self.time_ms_hide = timing.get_visible_end(3);
let time = get_time_str(self.time_ms_hide);
debug!("[W-{}] hide time updated to {}", self.number, time);
}
/// Get dimensions of the window
///
/// The dimensions of a unique window specify an area on the screen which may contain caption text.
pub fn get_dimensions(&self) -> Result<(i32, i32, i32, i32), String> {
let anchor = dtvcc_pen_anchor_point::new(self.anchor_point)?;
let (mut x1, mut x2, mut y1, mut y2) = match anchor {
dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_TOP_LEFT => (
self.anchor_vertical,
self.anchor_vertical + self.row_count,
self.anchor_horizontal,
self.anchor_horizontal + self.col_count,
),
dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_TOP_CENTER => (
self.anchor_vertical,
self.anchor_vertical + self.row_count,
self.anchor_horizontal - self.col_count,
self.anchor_horizontal + self.col_count / 2,
),
dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_TOP_RIGHT => (
self.anchor_vertical,
self.anchor_vertical + self.row_count,
self.anchor_horizontal - self.col_count,
self.anchor_horizontal,
),
dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_MIDDLE_LEFT => (
self.anchor_vertical - self.row_count / 2,
self.anchor_vertical + self.row_count / 2,
self.anchor_horizontal,
self.anchor_horizontal + self.col_count,
),
dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_MIDDLE_CENTER => (
self.anchor_vertical - self.row_count / 2,
self.anchor_vertical + self.row_count / 2,
self.anchor_horizontal - self.col_count / 2,
self.anchor_horizontal + self.col_count / 2,
),
dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_MIDDLE_RIGHT => (
self.anchor_vertical - self.row_count / 2,
self.anchor_vertical + self.row_count / 2,
self.anchor_horizontal - self.col_count,
self.anchor_horizontal,
),
dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_BOTTOM_LEFT => (
self.anchor_vertical - self.row_count,
self.anchor_vertical,
self.anchor_horizontal,
self.anchor_horizontal + self.col_count,
),
dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_BOTTOM_CENTER => (
self.anchor_vertical - self.row_count,
self.anchor_vertical,
self.anchor_horizontal - self.col_count / 2,
self.anchor_horizontal + self.col_count / 2,
),
dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_BOTTOM_RIGHT => (
self.anchor_vertical - self.row_count,
self.anchor_vertical,
self.anchor_horizontal - self.col_count,
self.anchor_horizontal,
),
};
if x1 < 0 {
x1 = 0
}
if y1 < 0 {
y1 = 0
}
if x2 > CCX_DTVCC_SCREENGRID_ROWS as i32 {
x2 = CCX_DTVCC_SCREENGRID_ROWS as i32
}
if y2 > CCX_DTVCC_SCREENGRID_COLUMNS as i32 {
y2 = CCX_DTVCC_SCREENGRID_COLUMNS as i32
}
Ok((x1, x2, y1, y2))
}
/// Clear all text from the window
pub fn clear_text(&mut self) {
// Set pen color to default value
self.pen_color_pattern = dtvcc_pen_color::default();
// Set pen attributes to default value
self.pen_attribs_pattern = dtvcc_pen_attribs::default();
for row in 0..CCX_DTVCC_MAX_ROWS as usize {
self.clear_row(row);
}
self.is_empty = 1;
}
/// Clear text from the selected row
pub fn clear_row(&mut self, row_index: usize) {
if is_true(self.memory_reserved) {
unsafe {
let layout = Layout::array::<dtvcc_symbol>(CCX_DTVCC_MAX_COLUMNS as usize);
if let Err(e) = layout {
error!("clear_row: Incorrect Layout, {}", e);
} else {
let layout = layout.unwrap();
// deallocate previous memory
dealloc(self.rows[row_index] as *mut u8, layout);
// allocate new zero initialized memory
let ptr = alloc_zeroed(layout);
if ptr.is_null() {
error!("clear_row: Not enough memory",);
}
self.rows[row_index] = ptr as *mut dtvcc_symbol;
}
}
for col in 0..CCX_DTVCC_MAX_COLUMNS as usize {
// Set pen attributes to default value
self.pen_attribs[row_index][col] = dtvcc_pen_attribs {
pen_size: dtvcc_pen_size::DTVCC_PEN_SIZE_STANDART as i32,
offset: 0,
text_tag: dtvcc_pen_text_tag::DTVCC_PEN_TEXT_TAG_UNDEFINED_12 as i32,
font_tag: 0,
edge_type: dtvcc_pen_edge::DTVCC_PEN_EDGE_NONE as i32,
underline: 0,
italic: 0,
};
// Set pen color to default value
self.pen_colors[row_index][col] = dtvcc_pen_color {
fg_color: 0x3F,
fg_opacity: 0,
bg_color: 0,
bg_opacity: 0,
edge_color: 0,
};
}
}
}
/// Roll-up the captions
///
/// Scroll all the rows above by 1 to achieve the rollup effect
pub fn rollup(&mut self) {
debug!("roller");
for row_index in 0..(self.row_count - 1) as usize {
let curr_row = self.rows[row_index];
let next_row = self.rows[row_index + 1] as *const dtvcc_symbol;
unsafe { copy_nonoverlapping(next_row, curr_row, CCX_DTVCC_MAX_COLUMNS as usize) };
for col_index in 0..CCX_DTVCC_MAX_COLUMNS as usize {
self.pen_colors[row_index][col_index] = self.pen_colors[row_index + 1][col_index];
self.pen_attribs[row_index][col_index] = self.pen_attribs[row_index + 1][col_index];
}
}
self.clear_row((self.row_count - 1) as usize);
}
}
impl dtvcc_window_pd {
/// Create new window direction
pub fn new(direction: i32) -> Result<Self, String> {
match direction {
0 => Ok(dtvcc_window_pd::DTVCC_WINDOW_PD_LEFT_RIGHT),
1 => Ok(dtvcc_window_pd::DTVCC_WINDOW_PD_RIGHT_LEFT),
2 => Ok(dtvcc_window_pd::DTVCC_WINDOW_PD_TOP_BOTTOM),
3 => Ok(dtvcc_window_pd::DTVCC_WINDOW_PD_BOTTOM_TOP),
_ => Err(String::from("Invalid print direction")),
}
}
}
impl dtvcc_pen_anchor_point {
/// Create new pen anchor point
pub fn new(anchor: i32) -> Result<Self, String> {
match anchor {
0 => Ok(dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_TOP_LEFT),
1 => Ok(dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_TOP_CENTER),
2 => Ok(dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_TOP_RIGHT),
3 => Ok(dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_MIDDLE_LEFT),
4 => Ok(dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_MIDDLE_CENTER),
5 => Ok(dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_MIDDLE_RIGHT),
6 => Ok(dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_BOTTOM_LEFT),
7 => Ok(dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_BOTTOM_CENTER),
8 => Ok(dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_BOTTOM_RIGHT),
_ => Err(String::from("Invalid pen anchor")),
}
}
}
/// Window style for a specific window preset
struct WindowStyle {
justify: dtvcc_window_justify,
print_direction: dtvcc_window_pd,
scroll_direction: dtvcc_window_sd,
word_wrap: u8,
display_effect: dtvcc_window_sde,
effect_direction: u8,
effect_speed: u8,
fill_color: u8,
fill_opacity: dtvcc_window_fo,
border_type: dtvcc_window_border,
border_color: u8,
}
impl WindowStyle {
/// Create new window style using a window preset
pub fn new(preset: WindowPreset) -> Self {
// All styles have these common attributes
let effect_direction = 0;
let effect_speed = 0;
let fill_color = 0;
let border_color = 0;
let display_effect = dtvcc_window_sde::DTVCC_WINDOW_SDE_SNAP;
let border_type = dtvcc_window_border::DTVCC_WINDOW_BORDER_NONE;
let (justify, pd, sd, word_wrap, fill_opacity) = match preset {
WindowPreset::NtscPopup => (
dtvcc_window_justify::DTVCC_WINDOW_JUSTIFY_LEFT,
dtvcc_window_pd::DTVCC_WINDOW_PD_LEFT_RIGHT,
dtvcc_window_sd::DTVCC_WINDOW_SD_BOTTOM_TOP,
0,
dtvcc_window_fo::DTVCC_WINDOW_FO_SOLID,
),
WindowPreset::Popup => (
dtvcc_window_justify::DTVCC_WINDOW_JUSTIFY_LEFT,
dtvcc_window_pd::DTVCC_WINDOW_PD_LEFT_RIGHT,
dtvcc_window_sd::DTVCC_WINDOW_SD_BOTTOM_TOP,
0,
dtvcc_window_fo::DTVCC_WINDOW_FO_TRANSPARENT,
),
WindowPreset::NtscCenteredPopup => (
dtvcc_window_justify::DTVCC_WINDOW_JUSTIFY_CENTER,
dtvcc_window_pd::DTVCC_WINDOW_PD_LEFT_RIGHT,
dtvcc_window_sd::DTVCC_WINDOW_SD_BOTTOM_TOP,
0,
dtvcc_window_fo::DTVCC_WINDOW_FO_SOLID,
),
WindowPreset::NtscRollup => (
dtvcc_window_justify::DTVCC_WINDOW_JUSTIFY_LEFT,
dtvcc_window_pd::DTVCC_WINDOW_PD_LEFT_RIGHT,
dtvcc_window_sd::DTVCC_WINDOW_SD_BOTTOM_TOP,
1,
dtvcc_window_fo::DTVCC_WINDOW_FO_SOLID,
),
WindowPreset::Rollup => (
dtvcc_window_justify::DTVCC_WINDOW_JUSTIFY_LEFT,
dtvcc_window_pd::DTVCC_WINDOW_PD_LEFT_RIGHT,
dtvcc_window_sd::DTVCC_WINDOW_SD_BOTTOM_TOP,
1,
dtvcc_window_fo::DTVCC_WINDOW_FO_TRANSPARENT,
),
WindowPreset::NtscCenteredRollup => (
dtvcc_window_justify::DTVCC_WINDOW_JUSTIFY_CENTER,
dtvcc_window_pd::DTVCC_WINDOW_PD_LEFT_RIGHT,
dtvcc_window_sd::DTVCC_WINDOW_SD_BOTTOM_TOP,
1,
dtvcc_window_fo::DTVCC_WINDOW_FO_SOLID,
),
WindowPreset::TickerTape => (
dtvcc_window_justify::DTVCC_WINDOW_JUSTIFY_LEFT,
dtvcc_window_pd::DTVCC_WINDOW_PD_TOP_BOTTOM,
dtvcc_window_sd::DTVCC_WINDOW_SD_RIGHT_LEFT,
0,
dtvcc_window_fo::DTVCC_WINDOW_FO_SOLID,
),
};
Self {
justify,
print_direction: pd,
scroll_direction: sd,
word_wrap,
display_effect,
effect_direction,
effect_speed,
fill_color,
fill_opacity,
border_type,
border_color,
}
}
}
/// Predefined window style ids
#[derive(Clone, Copy)]
pub enum WindowPreset {
/// #1 NTSC Style Popup Captions
NtscPopup = 1,
/// #2 Popup Captions w/o Black Background
Popup = 2,
/// #3 NTSC Style Centered Popup Captions
NtscCenteredPopup = 3,
/// #4 NTSC Style Rollup Captions
NtscRollup = 4,
/// #4 Rollup Captions w/o Black Background
Rollup = 5,
/// #6 NTSC Style Centered Rollup Captions
NtscCenteredRollup = 6,
/// #7 Ticker Tape
TickerTape = 7,
}
impl WindowPreset {
/// Returns a 'WindowPreset' according to the style id
pub fn get_style(style_id: u8) -> Result<Self, String> {
match style_id {
1 => Ok(WindowPreset::NtscPopup),
2 => Ok(WindowPreset::Popup),
3 => Ok(WindowPreset::NtscCenteredPopup),
4 => Ok(WindowPreset::NtscRollup),
5 => Ok(WindowPreset::Rollup),
6 => Ok(WindowPreset::NtscCenteredRollup),
7 => Ok(WindowPreset::TickerTape),
_ => Err("Invalid style".to_owned()),
}
}
}
/// Predefined pen style ids
#[derive(PartialEq)]
pub enum PenPreset {
/// #1 Default NTSC Style
NtscStyle,
/// #2 NTSC Style Mono w/ Serif
NtscStyleMonoSerif,
/// #3 NTSC Style Prop w/ Serif
NtscStylePropSerif,
/// #4 NTSC Style Mono w/o Serif
NtscStyleMono,
/// #5 NTSC Style Prop w/o Serif
NtscStyleProp,
/// #6 Mono w/o Serif, Bordered Text, No bg
MonoBordered,
/// #7 Prop w/o Serif, Bordered Text, No bg
PropBordered,
}
impl PenPreset {
/// Returns a 'PenPreset' according to the style id
pub fn get_style(style_id: u8) -> Result<Self, String> {
match style_id {
1 => Ok(PenPreset::NtscStyle),
2 => Ok(PenPreset::NtscStyleMonoSerif),
3 => Ok(PenPreset::NtscStylePropSerif),
4 => Ok(PenPreset::NtscStyleMono),
5 => Ok(PenPreset::NtscStyleProp),
6 => Ok(PenPreset::MonoBordered),
7 => Ok(PenPreset::PropBordered),
_ => Err("Invalid style".to_owned()),
}
}
}
/// Pen style for a specific pen preset
pub struct PenStyle {
/// always standard pen size
pen_size: dtvcc_pen_size,
/// Font style, ranged from 1-7
/// Not being used current in the C code(bindings)
_font_style: dtvcc_pen_font_style,
offset: dtvcc_pen_offset,
/// always no, i.e. 0
italics: u8,
/// always no, i.e. 0
underline: u8,
edge_type: dtvcc_pen_edge,
color: PenColor,
}
impl PenStyle {
/// Create new pen style using a pen preset
pub fn new(preset: PenPreset) -> Self {
// All styles have these common attributes
let pen_size = dtvcc_pen_size::DTVCC_PEN_SIZE_STANDART;
let offset = dtvcc_pen_offset::DTVCC_PEN_OFFSET_NORMAL;
let italics = 0;
let underline = 0;
let bg_opacity = match preset {
PenPreset::MonoBordered | PenPreset::PropBordered => Opacity::Transparent,
_ => Opacity::Solid,
};
let color = PenColor {
/// White(2,2,2) i.e 10,10,10 i.e 42
fg_color: 42,
fg_opacity: Opacity::Solid,
/// Either N/A or black, still always 0
bg_color: 0,
bg_opacity,
/// Either N/A or black, still always 0
edge_color: 0,
};
let (font_style, edge_type) = match preset {
PenPreset::NtscStyle => (
dtvcc_pen_font_style::DTVCC_PEN_FONT_STYLE_DEFAULT_OR_UNDEFINED,
dtvcc_pen_edge::DTVCC_PEN_EDGE_UNIFORM,
),
PenPreset::NtscStyleMonoSerif => (
dtvcc_pen_font_style::DTVCC_PEN_FONT_STYLE_MONOSPACED_WITH_SERIFS,
dtvcc_pen_edge::DTVCC_PEN_EDGE_UNIFORM,
),
PenPreset::NtscStylePropSerif => (
dtvcc_pen_font_style::DTVCC_PEN_FONT_STYLE_PROPORTIONALLY_SPACED_WITH_SERIFS,
dtvcc_pen_edge::DTVCC_PEN_EDGE_UNIFORM,
),
PenPreset::NtscStyleMono => (
dtvcc_pen_font_style::DTVCC_PEN_FONT_STYLE_MONOSPACED_WITHOUT_SERIFS,
dtvcc_pen_edge::DTVCC_PEN_EDGE_UNIFORM,
),
PenPreset::NtscStyleProp => (
dtvcc_pen_font_style::DTVCC_PEN_FONT_STYLE_PROPORTIONALLY_SPACED_WITHOUT_SERIFS,
dtvcc_pen_edge::DTVCC_PEN_EDGE_UNIFORM,
),
PenPreset::MonoBordered => (
dtvcc_pen_font_style::DTVCC_PEN_FONT_STYLE_MONOSPACED_WITHOUT_SERIFS,
dtvcc_pen_edge::DTVCC_PEN_EDGE_UNIFORM,
),
PenPreset::PropBordered => (
dtvcc_pen_font_style::DTVCC_PEN_FONT_STYLE_PROPORTIONALLY_SPACED_WITHOUT_SERIFS,
dtvcc_pen_edge::DTVCC_PEN_EDGE_UNIFORM,
),
};
Self {
pen_size,
_font_style: font_style,
offset,
italics,
underline,
edge_type,
color,
}
}
}
/// Pen Color attributes
///
/// Set by the SPC(SetPenColor) command. Refer Section 8.10.5.10 CEA-708-E
///
/// Text written to the current window will have the color attributes specified by
/// the most recent SetPenColor command written to the window.
struct PenColor {
/// Color of text forground body
fg_color: u8,
/// Opacity of text foreground body
fg_opacity: Opacity,
/// Color of background box surrounding the text
bg_color: u8,
/// Opacity of background box surrounding the text
bg_opacity: Opacity,
/// Color of the outlined edges of text
edge_color: u8,
}
/// Opacity of the window/pen colors
enum Opacity {
Solid = 0,
_Flash = 1,
_Translucent = 2,
Transparent = 3,
}
impl Default for dtvcc_pen_color {
/// Returns the default pen color
fn default() -> Self {
Self {
fg_color: 0x3F,
fg_opacity: 0,
bg_color: 0,
bg_opacity: 0,
edge_color: 0,
}
}
}
impl Default for dtvcc_pen_attribs {
/// Returns the default pen attributes
fn default() -> Self {
Self {
pen_size: dtvcc_pen_size::DTVCC_PEN_SIZE_STANDART as i32,
offset: 0,
text_tag: dtvcc_pen_text_tag::DTVCC_PEN_TEXT_TAG_UNDEFINED_12 as i32,
font_tag: 0,
edge_type: dtvcc_pen_edge::DTVCC_PEN_EDGE_NONE as i32,
underline: 0,
italic: 0,
}
}
}

169
src/rust/src/lib.rs Normal file
View File

@@ -0,0 +1,169 @@
//! Rust library for CCExtractor
//!
//! Currently we are in the process of porting the 708 decoder to rust. See [decoder]
// Allow C naming style
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
/// CCExtractor C bindings generated by bindgen
#[allow(clippy::all)]
pub mod bindings {
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
}
pub mod decoder;
pub mod utils;
#[cfg(windows)]
use std::os::windows::io::{FromRawHandle, RawHandle};
use std::{io::Write, os::raw::c_int};
use bindings::*;
use decoder::Dtvcc;
use utils::is_true;
use env_logger::{builder, Target};
use log::{warn, LevelFilter};
extern "C" {
static mut cb_708: c_int;
static mut cb_field1: c_int;
static mut cb_field2: c_int;
}
/// Initialize env logger with custom format, using stdout as target
#[no_mangle]
pub extern "C" fn ccxr_init_logger() {
builder()
.format(|buf, record| writeln!(buf, "[CEA-708] {}", record.args()))
.filter_level(LevelFilter::Debug)
.target(Target::Stdout)
.init();
}
/// Process cc_data
///
/// # Safety
/// dec_ctx should not be a null pointer
/// data should point to cc_data of length cc_count
#[no_mangle]
extern "C" fn ccxr_process_cc_data(
dec_ctx: *mut lib_cc_decode,
data: *const ::std::os::raw::c_uchar,
cc_count: c_int,
) -> c_int {
let mut ret = -1;
let mut cc_data: Vec<u8> = (0..cc_count * 3)
.map(|x| unsafe { *data.add(x as usize) })
.collect();
let dec_ctx = unsafe { &mut *dec_ctx };
let dtvcc_ctx = unsafe { &mut *dec_ctx.dtvcc };
let mut dtvcc = Dtvcc::new(dtvcc_ctx);
for cc_block in cc_data.chunks_exact_mut(3) {
if !validate_cc_pair(cc_block) {
continue;
}
let success = do_cb(dec_ctx, &mut dtvcc, cc_block);
if success {
ret = 0;
}
}
ret
}
/// Returns `true` if cc_block pair is valid
///
/// For CEA-708 data, only cc_valid is checked
/// For CEA-608 data, parity is also checked
pub fn validate_cc_pair(cc_block: &mut [u8]) -> bool {
let cc_valid = (cc_block[0] & 4) >> 2;
let cc_type = cc_block[0] & 3;
if cc_valid == 0 {
return false;
}
if cc_type == 0 || cc_type == 1 {
// For CEA-608 data we verify parity.
if verify_parity(cc_block[2]) {
// If the second byte doesn't pass parity, ignore pair
return false;
}
if verify_parity(cc_block[1]) {
// If the first byte doesn't pass parity,
// we replace it with a solid blank and process the pair.
cc_block[1] = 0x7F;
}
}
true
}
/// Returns `true` if data has odd parity
///
/// CC uses odd parity (i.e., # of 1's in byte is odd.)
pub fn verify_parity(data: u8) -> bool {
if data.count_ones() & 1 == 1 {
return true;
}
false
}
/// Process CC data according to its type
pub fn do_cb(ctx: &mut lib_cc_decode, dtvcc: &mut Dtvcc, cc_block: &[u8]) -> bool {
let cc_valid = (cc_block[0] & 4) >> 2;
let cc_type = cc_block[0] & 3;
let mut timeok = true;
if ctx.write_format != ccx_output_format::CCX_OF_DVDRAW
&& ctx.write_format != ccx_output_format::CCX_OF_RAW
&& (cc_block[0] == 0xFA || cc_block[0] == 0xFC || cc_block[0] == 0xFD)
&& (cc_block[1] & 0x7F) == 0
&& (cc_block[2] & 0x7F) == 0
{
return true;
}
if cc_valid == 1 || cc_type == 3 {
ctx.cc_stats[cc_type as usize] += 1;
match cc_type {
// Type 0 and 1 are for CEA-608 data. Handled by C code, do nothing
0 | 1 => {}
// Type 2 and 3 are for CEA-708 data.
2 | 3 => {
let current_time = unsafe { (*ctx.timing).get_fts(ctx.current_field as u8) };
ctx.current_field = 3;
// Check whether current time is within start and end bounds
if is_true(ctx.extraction_start.set)
&& current_time < ctx.extraction_start.time_in_ms
{
timeok = false;
}
if is_true(ctx.extraction_end.set) && current_time > ctx.extraction_end.time_in_ms {
timeok = false;
ctx.processed_enough = 1;
}
if timeok && ctx.write_format != ccx_output_format::CCX_OF_RAW {
dtvcc.process_cc_data(cc_valid, cc_type, cc_block[1], cc_block[2]);
}
unsafe { cb_708 += 1 }
}
_ => warn!("Invalid cc_type"),
}
}
true
}
#[cfg(windows)]
#[no_mangle]
extern "C" fn ccxr_close_handle(handle: RawHandle) {
use std::fs::File;
if handle.is_null() {
return;
}
unsafe {
// File will close automatically (due to Drop) once it goes out of scope
let _file = File::from_raw_handle(handle);
}
}

11
src/rust/src/utils.rs Normal file
View File

@@ -0,0 +1,11 @@
//! Some utility functions to deal with values from C bindings
/// Check if the value is true (Set to 1). Use only for values from C bindings
pub fn is_true<T: Into<i32>>(val: T) -> bool {
val.into() == 1
}
/// Check if the value is false (Set to 0). Use only for values from C bindings
pub fn is_false<T: Into<i32>>(val: T) -> bool {
val.into() == 0
}

7
src/rust/wrapper.h Normal file
View File

@@ -0,0 +1,7 @@
#include "../lib_ccx/ccx_decoders_708.h"
#include "../lib_ccx/ccx_decoders_common.h"
#include "../lib_ccx/ccx_dtvcc.h"
#include "../lib_ccx/ccx_decoders_708_output.h"
#include "../lib_ccx/ccx_decoders_708_encoding.h"
#include "../lib_ccx/ccx_common_timing.h"
#include "../lib_ccx/lib_ccx.h"

136
src/thirdparty/libpng/arm/arm_init.c vendored Normal file
View File

@@ -0,0 +1,136 @@
/* arm_init.c - NEON optimised filter functions
*
* Copyright (c) 2018 Cosmin Truta
* Copyright (c) 2014,2016 Glenn Randers-Pehrson
* Written by Mans Rullgard, 2011.
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*/
/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are
* called.
*/
#define _POSIX_SOURCE 1
#include "../pngpriv.h"
#ifdef PNG_READ_SUPPORTED
#if PNG_ARM_NEON_OPT > 0
#ifdef PNG_ARM_NEON_CHECK_SUPPORTED /* Do run-time checks */
/* WARNING: it is strongly recommended that you do not build libpng with
* run-time checks for CPU features if at all possible. In the case of the ARM
* NEON instructions there is no processor-specific way of detecting the
* presence of the required support, therefore run-time detection is extremely
* OS specific.
*
* You may set the macro PNG_ARM_NEON_FILE to the file name of file containing
* a fragment of C source code which defines the png_have_neon function. There
* are a number of implementations in contrib/arm-neon, but the only one that
* has partial support is contrib/arm-neon/linux.c - a generic Linux
* implementation which reads /proc/cpufino.
*/
#ifndef PNG_ARM_NEON_FILE
# ifdef __linux__
# define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c"
# endif
#endif
#ifdef PNG_ARM_NEON_FILE
#include <signal.h> /* for sig_atomic_t */
static int png_have_neon(png_structp png_ptr);
#include PNG_ARM_NEON_FILE
#else /* PNG_ARM_NEON_FILE */
# error "PNG_ARM_NEON_FILE undefined: no support for run-time ARM NEON checks"
#endif /* PNG_ARM_NEON_FILE */
#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */
#ifndef PNG_ALIGNED_MEMORY_SUPPORTED
# error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED"
#endif
void
png_init_filter_functions_neon(png_structp pp, unsigned int bpp)
{
/* The switch statement is compiled in for ARM_NEON_API, the call to
* png_have_neon is compiled in for ARM_NEON_CHECK. If both are defined
* the check is only performed if the API has not set the NEON option on
* or off explicitly. In this case the check controls what happens.
*
* If the CHECK is not compiled in and the option is UNSET the behavior prior
* to 1.6.7 was to use the NEON code - this was a bug caused by having the
* wrong order of the 'ON' and 'default' cases. UNSET now defaults to OFF,
* as documented in png.h
*/
png_debug(1, "in png_init_filter_functions_neon");
#ifdef PNG_ARM_NEON_API_SUPPORTED
switch ((pp->options >> PNG_ARM_NEON) & 3)
{
case PNG_OPTION_UNSET:
/* Allow the run-time check to execute if it has been enabled -
* thus both API and CHECK can be turned on. If it isn't supported
* this case will fall through to the 'default' below, which just
* returns.
*/
#endif /* PNG_ARM_NEON_API_SUPPORTED */
#ifdef PNG_ARM_NEON_CHECK_SUPPORTED
{
static volatile sig_atomic_t no_neon = -1; /* not checked */
if (no_neon < 0)
no_neon = !png_have_neon(pp);
if (no_neon)
return;
}
#ifdef PNG_ARM_NEON_API_SUPPORTED
break;
#endif
#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */
#ifdef PNG_ARM_NEON_API_SUPPORTED
default: /* OFF or INVALID */
return;
case PNG_OPTION_ON:
/* Option turned on */
break;
}
#endif
/* IMPORTANT: any new external functions used here must be declared using
* PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the
* 'prefix' option to configure works:
*
* ./configure --with-libpng-prefix=foobar_
*
* Verify you have got this right by running the above command, doing a build
* and examining pngprefix.h; it must contain a #define for every external
* function you add. (Notice that this happens automatically for the
* initialization function.)
*/
pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon;
if (bpp == 3)
{
pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon;
pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon;
pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
png_read_filter_row_paeth3_neon;
}
else if (bpp == 4)
{
pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon;
pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon;
pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
png_read_filter_row_paeth4_neon;
}
}
#endif /* PNG_ARM_NEON_OPT > 0 */
#endif /* READ */

253
src/thirdparty/libpng/arm/filter_neon.S vendored Normal file
View File

@@ -0,0 +1,253 @@
/* filter_neon.S - NEON optimised filter functions
*
* Copyright (c) 2018 Cosmin Truta
* Copyright (c) 2014,2017 Glenn Randers-Pehrson
* Written by Mans Rullgard, 2011.
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*/
/* This is required to get the symbol renames, which are #defines, and the
* definitions (or not) of PNG_ARM_NEON_OPT and PNG_ARM_NEON_IMPLEMENTATION.
*/
#define PNG_VERSION_INFO_ONLY
#include "../pngpriv.h"
#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits /* mark stack as non-executable */
#endif
#ifdef PNG_READ_SUPPORTED
/* Assembler NEON support - only works for 32-bit ARM (i.e. it does not work for
* ARM64). The code in arm/filter_neon_intrinsics.c supports ARM64, however it
* only works if -mfpu=neon is specified on the GCC command line. See pngpriv.h
* for the logic which sets PNG_USE_ARM_NEON_ASM:
*/
#if PNG_ARM_NEON_IMPLEMENTATION == 2 /* hand-coded assembler */
#if PNG_ARM_NEON_OPT > 0
#ifdef __ELF__
# define ELF
#else
# define ELF @
#endif
.arch armv7-a
.fpu neon
.macro func name, export=0
.macro endfunc
ELF .size \name, . - \name
.endfunc
.purgem endfunc
.endm
.text
/* Explicitly specifying alignment here because some versions of
* GAS don't align code correctly. This is harmless in correctly
* written versions of GAS.
*/
.align 2
.if \export
.global \name
.endif
ELF .type \name, STT_FUNC
.func \name
\name:
.endm
func png_read_filter_row_sub4_neon, export=1
ldr r3, [r0, #4] @ rowbytes
vmov.i8 d3, #0
1:
vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128]
vadd.u8 d0, d3, d4
vadd.u8 d1, d0, d5
vadd.u8 d2, d1, d6
vadd.u8 d3, d2, d7
vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
subs r3, r3, #16
bgt 1b
bx lr
endfunc
func png_read_filter_row_sub3_neon, export=1
ldr r3, [r0, #4] @ rowbytes
vmov.i8 d3, #0
mov r0, r1
mov r2, #3
mov r12, #12
vld1.8 {q11}, [r0], r12
1:
vext.8 d5, d22, d23, #3
vadd.u8 d0, d3, d22
vext.8 d6, d22, d23, #6
vadd.u8 d1, d0, d5
vext.8 d7, d23, d23, #1
vld1.8 {q11}, [r0], r12
vst1.32 {d0[0]}, [r1,:32], r2
vadd.u8 d2, d1, d6
vst1.32 {d1[0]}, [r1], r2
vadd.u8 d3, d2, d7
vst1.32 {d2[0]}, [r1], r2
vst1.32 {d3[0]}, [r1], r2
subs r3, r3, #12
bgt 1b
bx lr
endfunc
func png_read_filter_row_up_neon, export=1
ldr r3, [r0, #4] @ rowbytes
1:
vld1.8 {q0}, [r1,:128]
vld1.8 {q1}, [r2,:128]!
vadd.u8 q0, q0, q1
vst1.8 {q0}, [r1,:128]!
subs r3, r3, #16
bgt 1b
bx lr
endfunc
func png_read_filter_row_avg4_neon, export=1
ldr r12, [r0, #4] @ rowbytes
vmov.i8 d3, #0
1:
vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128]
vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]!
vhadd.u8 d0, d3, d16
vadd.u8 d0, d0, d4
vhadd.u8 d1, d0, d17
vadd.u8 d1, d1, d5
vhadd.u8 d2, d1, d18
vadd.u8 d2, d2, d6
vhadd.u8 d3, d2, d19
vadd.u8 d3, d3, d7
vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
subs r12, r12, #16
bgt 1b
bx lr
endfunc
func png_read_filter_row_avg3_neon, export=1
push {r4,lr}
ldr r12, [r0, #4] @ rowbytes
vmov.i8 d3, #0
mov r0, r1
mov r4, #3
mov lr, #12
vld1.8 {q11}, [r0], lr
1:
vld1.8 {q10}, [r2], lr
vext.8 d5, d22, d23, #3
vhadd.u8 d0, d3, d20
vext.8 d17, d20, d21, #3
vadd.u8 d0, d0, d22
vext.8 d6, d22, d23, #6
vhadd.u8 d1, d0, d17
vext.8 d18, d20, d21, #6
vadd.u8 d1, d1, d5
vext.8 d7, d23, d23, #1
vld1.8 {q11}, [r0], lr
vst1.32 {d0[0]}, [r1,:32], r4
vhadd.u8 d2, d1, d18
vst1.32 {d1[0]}, [r1], r4
vext.8 d19, d21, d21, #1
vadd.u8 d2, d2, d6
vhadd.u8 d3, d2, d19
vst1.32 {d2[0]}, [r1], r4
vadd.u8 d3, d3, d7
vst1.32 {d3[0]}, [r1], r4
subs r12, r12, #12
bgt 1b
pop {r4,pc}
endfunc
.macro paeth rx, ra, rb, rc
vaddl.u8 q12, \ra, \rb @ a + b
vaddl.u8 q15, \rc, \rc @ 2*c
vabdl.u8 q13, \rb, \rc @ pa
vabdl.u8 q14, \ra, \rc @ pb
vabd.u16 q15, q12, q15 @ pc
vcle.u16 q12, q13, q14 @ pa <= pb
vcle.u16 q13, q13, q15 @ pa <= pc
vcle.u16 q14, q14, q15 @ pb <= pc
vand q12, q12, q13 @ pa <= pb && pa <= pc
vmovn.u16 d28, q14
vmovn.u16 \rx, q12
vbsl d28, \rb, \rc
vbsl \rx, \ra, d28
.endm
func png_read_filter_row_paeth4_neon, export=1
ldr r12, [r0, #4] @ rowbytes
vmov.i8 d3, #0
vmov.i8 d20, #0
1:
vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128]
vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]!
paeth d0, d3, d16, d20
vadd.u8 d0, d0, d4
paeth d1, d0, d17, d16
vadd.u8 d1, d1, d5
paeth d2, d1, d18, d17
vadd.u8 d2, d2, d6
paeth d3, d2, d19, d18
vmov d20, d19
vadd.u8 d3, d3, d7
vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
subs r12, r12, #16
bgt 1b
bx lr
endfunc
func png_read_filter_row_paeth3_neon, export=1
push {r4,lr}
ldr r12, [r0, #4] @ rowbytes
vmov.i8 d3, #0
vmov.i8 d4, #0
mov r0, r1
mov r4, #3
mov lr, #12
vld1.8 {q11}, [r0], lr
1:
vld1.8 {q10}, [r2], lr
paeth d0, d3, d20, d4
vext.8 d5, d22, d23, #3
vadd.u8 d0, d0, d22
vext.8 d17, d20, d21, #3
paeth d1, d0, d17, d20
vst1.32 {d0[0]}, [r1,:32], r4
vext.8 d6, d22, d23, #6
vadd.u8 d1, d1, d5
vext.8 d18, d20, d21, #6
paeth d2, d1, d18, d17
vext.8 d7, d23, d23, #1
vld1.8 {q11}, [r0], lr
vst1.32 {d1[0]}, [r1], r4
vadd.u8 d2, d2, d6
vext.8 d19, d21, d21, #1
paeth d3, d2, d19, d18
vst1.32 {d2[0]}, [r1], r4
vmov d4, d19
vadd.u8 d3, d3, d7
vst1.32 {d3[0]}, [r1], r4
subs r12, r12, #12
bgt 1b
pop {r4,pc}
endfunc
#endif /* PNG_ARM_NEON_OPT > 0 */
#endif /* PNG_ARM_NEON_IMPLEMENTATION == 2 (assembler) */
#endif /* READ */

View File

@@ -0,0 +1,402 @@
/* filter_neon_intrinsics.c - NEON optimised filter functions
*
* Copyright (c) 2018 Cosmin Truta
* Copyright (c) 2014,2016 Glenn Randers-Pehrson
* Written by James Yu <james.yu at linaro.org>, October 2013.
* Based on filter_neon.S, written by Mans Rullgard, 2011.
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*/
#include "../pngpriv.h"
#ifdef PNG_READ_SUPPORTED
/* This code requires -mfpu=neon on the command line: */
#if PNG_ARM_NEON_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */
#if defined(_MSC_VER) && defined(_M_ARM64)
# include <arm64_neon.h>
#else
# include <arm_neon.h>
#endif
/* libpng row pointers are not necessarily aligned to any particular boundary,
* however this code will only work with appropriate alignment. arm/arm_init.c
* checks for this (and will not compile unless it is done). This code uses
* variants of png_aligncast to avoid compiler warnings.
*/
#define png_ptr(type,pointer) png_aligncast(type *,pointer)
#define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer)
/* The following relies on a variable 'temp_pointer' being declared with type
* 'type'. This is written this way just to hide the GCC strict aliasing
* warning; note that the code is safe because there never is an alias between
* the input and output pointers.
*
* When compiling with MSVC ARM64, the png_ldr macro can't be passed directly
* to vst4_lane_u32, because of an internal compiler error inside MSVC.
* To avoid this compiler bug, we use a temporary variable (vdest_val) to store
* the result of png_ldr.
*/
#define png_ldr(type,pointer)\
(temp_pointer = png_ptr(type,pointer), *temp_pointer)
#if PNG_ARM_NEON_OPT > 0
void
png_read_filter_row_up_neon(png_row_infop row_info, png_bytep row,
png_const_bytep prev_row)
{
png_bytep rp = row;
png_bytep rp_stop = row + row_info->rowbytes;
png_const_bytep pp = prev_row;
png_debug(1, "in png_read_filter_row_up_neon");
for (; rp < rp_stop; rp += 16, pp += 16)
{
uint8x16_t qrp, qpp;
qrp = vld1q_u8(rp);
qpp = vld1q_u8(pp);
qrp = vaddq_u8(qrp, qpp);
vst1q_u8(rp, qrp);
}
}
void
png_read_filter_row_sub3_neon(png_row_infop row_info, png_bytep row,
png_const_bytep prev_row)
{
png_bytep rp = row;
png_bytep rp_stop = row + row_info->rowbytes;
uint8x16_t vtmp = vld1q_u8(rp);
uint8x8x2_t *vrpt = png_ptr(uint8x8x2_t, &vtmp);
uint8x8x2_t vrp = *vrpt;
uint8x8x4_t vdest;
vdest.val[3] = vdup_n_u8(0);
png_debug(1, "in png_read_filter_row_sub3_neon");
for (; rp < rp_stop;)
{
uint8x8_t vtmp1, vtmp2;
uint32x2_t *temp_pointer;
vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]);
vtmp2 = vext_u8(vrp.val[0], vrp.val[1], 6);
vdest.val[1] = vadd_u8(vdest.val[0], vtmp1);
vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
vdest.val[2] = vadd_u8(vdest.val[1], vtmp2);
vdest.val[3] = vadd_u8(vdest.val[2], vtmp1);
vtmp = vld1q_u8(rp + 12);
vrpt = png_ptr(uint8x8x2_t, &vtmp);
vrp = *vrpt;
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
rp += 3;
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
rp += 3;
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
rp += 3;
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
rp += 3;
}
PNG_UNUSED(prev_row)
}
void
png_read_filter_row_sub4_neon(png_row_infop row_info, png_bytep row,
png_const_bytep prev_row)
{
png_bytep rp = row;
png_bytep rp_stop = row + row_info->rowbytes;
uint8x8x4_t vdest;
vdest.val[3] = vdup_n_u8(0);
png_debug(1, "in png_read_filter_row_sub4_neon");
for (; rp < rp_stop; rp += 16)
{
uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp));
uint8x8x4_t *vrpt = png_ptr(uint8x8x4_t,&vtmp);
uint8x8x4_t vrp = *vrpt;
uint32x2x4_t *temp_pointer;
uint32x2x4_t vdest_val;
vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]);
vdest.val[1] = vadd_u8(vdest.val[0], vrp.val[1]);
vdest.val[2] = vadd_u8(vdest.val[1], vrp.val[2]);
vdest.val[3] = vadd_u8(vdest.val[2], vrp.val[3]);
vdest_val = png_ldr(uint32x2x4_t, &vdest);
vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0);
}
PNG_UNUSED(prev_row)
}
void
png_read_filter_row_avg3_neon(png_row_infop row_info, png_bytep row,
png_const_bytep prev_row)
{
png_bytep rp = row;
png_const_bytep pp = prev_row;
png_bytep rp_stop = row + row_info->rowbytes;
uint8x16_t vtmp;
uint8x8x2_t *vrpt;
uint8x8x2_t vrp;
uint8x8x4_t vdest;
vdest.val[3] = vdup_n_u8(0);
vtmp = vld1q_u8(rp);
vrpt = png_ptr(uint8x8x2_t,&vtmp);
vrp = *vrpt;
png_debug(1, "in png_read_filter_row_avg3_neon");
for (; rp < rp_stop; pp += 12)
{
uint8x8_t vtmp1, vtmp2, vtmp3;
uint8x8x2_t *vppt;
uint8x8x2_t vpp;
uint32x2_t *temp_pointer;
vtmp = vld1q_u8(pp);
vppt = png_ptr(uint8x8x2_t,&vtmp);
vpp = *vppt;
vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]);
vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3);
vtmp3 = vext_u8(vrp.val[0], vrp.val[1], 6);
vdest.val[1] = vhadd_u8(vdest.val[0], vtmp2);
vdest.val[1] = vadd_u8(vdest.val[1], vtmp1);
vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 6);
vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
vtmp = vld1q_u8(rp + 12);
vrpt = png_ptr(uint8x8x2_t,&vtmp);
vrp = *vrpt;
vdest.val[2] = vhadd_u8(vdest.val[1], vtmp2);
vdest.val[2] = vadd_u8(vdest.val[2], vtmp3);
vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1);
vdest.val[3] = vhadd_u8(vdest.val[2], vtmp2);
vdest.val[3] = vadd_u8(vdest.val[3], vtmp1);
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
rp += 3;
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
rp += 3;
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
rp += 3;
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
rp += 3;
}
}
void
png_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row,
png_const_bytep prev_row)
{
png_bytep rp = row;
png_bytep rp_stop = row + row_info->rowbytes;
png_const_bytep pp = prev_row;
uint8x8x4_t vdest;
vdest.val[3] = vdup_n_u8(0);
png_debug(1, "in png_read_filter_row_avg4_neon");
for (; rp < rp_stop; rp += 16, pp += 16)
{
uint32x2x4_t vtmp;
uint8x8x4_t *vrpt, *vppt;
uint8x8x4_t vrp, vpp;
uint32x2x4_t *temp_pointer;
uint32x2x4_t vdest_val;
vtmp = vld4_u32(png_ptr(uint32_t,rp));
vrpt = png_ptr(uint8x8x4_t,&vtmp);
vrp = *vrpt;
vtmp = vld4_u32(png_ptrc(uint32_t,pp));
vppt = png_ptr(uint8x8x4_t,&vtmp);
vpp = *vppt;
vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]);
vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
vdest.val[1] = vhadd_u8(vdest.val[0], vpp.val[1]);
vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]);
vdest.val[2] = vhadd_u8(vdest.val[1], vpp.val[2]);
vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]);
vdest.val[3] = vhadd_u8(vdest.val[2], vpp.val[3]);
vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]);
vdest_val = png_ldr(uint32x2x4_t, &vdest);
vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0);
}
}
static uint8x8_t
paeth(uint8x8_t a, uint8x8_t b, uint8x8_t c)
{
uint8x8_t d, e;
uint16x8_t p1, pa, pb, pc;
p1 = vaddl_u8(a, b); /* a + b */
pc = vaddl_u8(c, c); /* c * 2 */
pa = vabdl_u8(b, c); /* pa */
pb = vabdl_u8(a, c); /* pb */
pc = vabdq_u16(p1, pc); /* pc */
p1 = vcleq_u16(pa, pb); /* pa <= pb */
pa = vcleq_u16(pa, pc); /* pa <= pc */
pb = vcleq_u16(pb, pc); /* pb <= pc */
p1 = vandq_u16(p1, pa); /* pa <= pb && pa <= pc */
d = vmovn_u16(pb);
e = vmovn_u16(p1);
d = vbsl_u8(d, b, c);
e = vbsl_u8(e, a, d);
return e;
}
void
png_read_filter_row_paeth3_neon(png_row_infop row_info, png_bytep row,
png_const_bytep prev_row)
{
png_bytep rp = row;
png_const_bytep pp = prev_row;
png_bytep rp_stop = row + row_info->rowbytes;
uint8x16_t vtmp;
uint8x8x2_t *vrpt;
uint8x8x2_t vrp;
uint8x8_t vlast = vdup_n_u8(0);
uint8x8x4_t vdest;
vdest.val[3] = vdup_n_u8(0);
vtmp = vld1q_u8(rp);
vrpt = png_ptr(uint8x8x2_t,&vtmp);
vrp = *vrpt;
png_debug(1, "in png_read_filter_row_paeth3_neon");
for (; rp < rp_stop; pp += 12)
{
uint8x8x2_t *vppt;
uint8x8x2_t vpp;
uint8x8_t vtmp1, vtmp2, vtmp3;
uint32x2_t *temp_pointer;
vtmp = vld1q_u8(pp);
vppt = png_ptr(uint8x8x2_t,&vtmp);
vpp = *vppt;
vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast);
vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3);
vdest.val[1] = paeth(vdest.val[0], vtmp2, vpp.val[0]);
vdest.val[1] = vadd_u8(vdest.val[1], vtmp1);
vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 6);
vtmp3 = vext_u8(vpp.val[0], vpp.val[1], 6);
vdest.val[2] = paeth(vdest.val[1], vtmp3, vtmp2);
vdest.val[2] = vadd_u8(vdest.val[2], vtmp1);
vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1);
vtmp = vld1q_u8(rp + 12);
vrpt = png_ptr(uint8x8x2_t,&vtmp);
vrp = *vrpt;
vdest.val[3] = paeth(vdest.val[2], vtmp2, vtmp3);
vdest.val[3] = vadd_u8(vdest.val[3], vtmp1);
vlast = vtmp2;
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
rp += 3;
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
rp += 3;
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
rp += 3;
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
rp += 3;
}
}
void
png_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row,
png_const_bytep prev_row)
{
png_bytep rp = row;
png_bytep rp_stop = row + row_info->rowbytes;
png_const_bytep pp = prev_row;
uint8x8_t vlast = vdup_n_u8(0);
uint8x8x4_t vdest;
vdest.val[3] = vdup_n_u8(0);
png_debug(1, "in png_read_filter_row_paeth4_neon");
for (; rp < rp_stop; rp += 16, pp += 16)
{
uint32x2x4_t vtmp;
uint8x8x4_t *vrpt, *vppt;
uint8x8x4_t vrp, vpp;
uint32x2x4_t *temp_pointer;
uint32x2x4_t vdest_val;
vtmp = vld4_u32(png_ptr(uint32_t,rp));
vrpt = png_ptr(uint8x8x4_t,&vtmp);
vrp = *vrpt;
vtmp = vld4_u32(png_ptrc(uint32_t,pp));
vppt = png_ptr(uint8x8x4_t,&vtmp);
vpp = *vppt;
vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast);
vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
vdest.val[1] = paeth(vdest.val[0], vpp.val[1], vpp.val[0]);
vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]);
vdest.val[2] = paeth(vdest.val[1], vpp.val[2], vpp.val[1]);
vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]);
vdest.val[3] = paeth(vdest.val[2], vpp.val[3], vpp.val[2]);
vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]);
vlast = vpp.val[3];
vdest_val = png_ldr(uint32x2x4_t, &vdest);
vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0);
}
}
#endif /* PNG_ARM_NEON_OPT > 0 */
#endif /* PNG_ARM_NEON_IMPLEMENTATION == 1 (intrinsics) */
#endif /* READ */

View File

@@ -0,0 +1,149 @@
/* palette_neon_intrinsics.c - NEON optimised palette expansion functions
*
* Copyright (c) 2018-2019 Cosmin Truta
* Copyright (c) 2017-2018 Arm Holdings. All rights reserved.
* Written by Richard Townsend <Richard.Townsend@arm.com>, February 2017.
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*/
#include "../pngpriv.h"
#if PNG_ARM_NEON_IMPLEMENTATION == 1
#if defined(_MSC_VER) && defined(_M_ARM64)
# include <arm64_neon.h>
#else
# include <arm_neon.h>
#endif
/* Build an RGBA8 palette from the separate RGB and alpha palettes. */
void
png_riffle_palette_neon(png_structrp png_ptr)
{
png_const_colorp palette = png_ptr->palette;
png_bytep riffled_palette = png_ptr->riffled_palette;
png_const_bytep trans_alpha = png_ptr->trans_alpha;
int num_trans = png_ptr->num_trans;
int i;
png_debug(1, "in png_riffle_palette_neon");
/* Initially black, opaque. */
uint8x16x4_t w = {{
vdupq_n_u8(0x00),
vdupq_n_u8(0x00),
vdupq_n_u8(0x00),
vdupq_n_u8(0xff),
}};
/* First, riffle the RGB colours into an RGBA8 palette.
* The alpha component is set to opaque for now.
*/
for (i = 0; i < 256; i += 16)
{
uint8x16x3_t v = vld3q_u8((png_const_bytep)(palette + i));
w.val[0] = v.val[0];
w.val[1] = v.val[1];
w.val[2] = v.val[2];
vst4q_u8(riffled_palette + (i << 2), w);
}
/* Fix up the missing transparency values. */
for (i = 0; i < num_trans; i++)
riffled_palette[(i << 2) + 3] = trans_alpha[i];
}
/* Expands a palettized row into RGBA8. */
int
png_do_expand_palette_rgba8_neon(png_structrp png_ptr, png_row_infop row_info,
png_const_bytep row, png_bytepp ssp, png_bytepp ddp)
{
png_uint_32 row_width = row_info->width;
const png_uint_32 *riffled_palette =
(const png_uint_32 *)png_ptr->riffled_palette;
const png_int_32 pixels_per_chunk = 4;
int i;
png_debug(1, "in png_do_expand_palette_rgba8_neon");
if (row_width < pixels_per_chunk)
return 0;
/* This function originally gets the last byte of the output row.
* The NEON part writes forward from a given position, so we have
* to seek this back by 4 pixels x 4 bytes.
*/
*ddp = *ddp - ((pixels_per_chunk * sizeof(png_uint_32)) - 1);
for (i = 0; i < row_width; i += pixels_per_chunk)
{
uint32x4_t cur;
png_bytep sp = *ssp - i, dp = *ddp - (i << 2);
cur = vld1q_dup_u32 (riffled_palette + *(sp - 3));
cur = vld1q_lane_u32(riffled_palette + *(sp - 2), cur, 1);
cur = vld1q_lane_u32(riffled_palette + *(sp - 1), cur, 2);
cur = vld1q_lane_u32(riffled_palette + *(sp - 0), cur, 3);
vst1q_u32((void *)dp, cur);
}
if (i != row_width)
{
/* Remove the amount that wasn't processed. */
i -= pixels_per_chunk;
}
/* Decrement output pointers. */
*ssp = *ssp - i;
*ddp = *ddp - (i << 2);
return i;
}
/* Expands a palettized row into RGB8. */
int
png_do_expand_palette_rgb8_neon(png_structrp png_ptr, png_row_infop row_info,
png_const_bytep row, png_bytepp ssp, png_bytepp ddp)
{
png_uint_32 row_width = row_info->width;
png_const_bytep palette = (png_const_bytep)png_ptr->palette;
const png_uint_32 pixels_per_chunk = 8;
int i;
png_debug(1, "in png_do_expand_palette_rgb8_neon");
if (row_width <= pixels_per_chunk)
return 0;
/* Seeking this back by 8 pixels x 3 bytes. */
*ddp = *ddp - ((pixels_per_chunk * sizeof(png_color)) - 1);
for (i = 0; i < row_width; i += pixels_per_chunk)
{
uint8x8x3_t cur;
png_bytep sp = *ssp - i, dp = *ddp - ((i << 1) + i);
cur = vld3_dup_u8(palette + sizeof(png_color) * (*(sp - 7)));
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 6)), cur, 1);
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 5)), cur, 2);
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 4)), cur, 3);
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 3)), cur, 4);
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 2)), cur, 5);
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 1)), cur, 6);
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 0)), cur, 7);
vst3_u8((void *)dp, cur);
}
if (i != row_width)
{
/* Remove the amount that wasn't processed. */
i -= pixels_per_chunk;
}
/* Decrement output pointers. */
*ssp = *ssp - i;
*ddp = *ddp - ((i << 1) + i);
return i;
}
#endif /* PNG_ARM_NEON_IMPLEMENTATION */

View File

@@ -5,8 +5,6 @@ VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ccextractor", "ccextractor.vcxproj", "{0F0063C4-BCBC-4379-A6D5-84A5669C940A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ccextractorGUI", "ccextractorGUI.vcxproj", "{74290DA6-174D-4F4B-A48E-F30B824B7925}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32

View File

@@ -334,6 +334,7 @@
<ProjectGuid>{0F0063C4-BCBC-4379-A6D5-84A5669C940A}</ProjectGuid>
<RootNamespace>ccextractor</RootNamespace>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@@ -342,7 +343,7 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
@@ -350,15 +351,15 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Full|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v140_xp</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Full|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Full|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
@@ -366,7 +367,7 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Full|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -421,7 +422,7 @@
<LinkIncremental>true</LinkIncremental>
<TargetName>ccextractorwin</TargetName>
<IncludePath>$(ProjectDir)\libs\include;$(IncludePath)</IncludePath>
<LibraryPath>$(ProjectDir)\libs\lib;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86)</LibraryPath>
<LibraryPath>$(ProjectDir)\libs\lib;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Full|Win32'">
<OutDir>Release-Full\</OutDir>
@@ -435,7 +436,7 @@
<LinkIncremental>false</LinkIncremental>
<TargetName>ccextractorwin</TargetName>
<IncludePath>$(ProjectDir)\libs\include;$(IncludePath)</IncludePath>
<LibraryPath>$(ProjectDir)\libs\lib;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86)</LibraryPath>
<LibraryPath>$(ProjectDir)\libs\lib;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>Release\</OutDir>
@@ -450,7 +451,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src\thirdparty\win_spec_incld;..\src\lib_ccx;..\src\thirdparty\lib_hash;..\src\lib_ccx\zvbi;..\src\thirdparty\protobuf-c;..\src\thirdparty\gpacmp4;..\src\thirdparty\win_iconv;..\src\thirdparty\zlib;..\src\thirdparty\libpng;..\src\thirdparty;..\src;libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src;..\src\thirdparty\win_spec_incld;..\src\lib_ccx;..\src\thirdparty\lib_hash;..\src\lib_ccx\zvbi;..\src\thirdparty\protobuf-c;..\src\thirdparty\gpacmp4;..\src\thirdparty\win_iconv;..\src\thirdparty\zlib;..\src\thirdparty\libpng;..\src\thirdparty;..\src;libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;FT2_BUILD_LIBRARY;GPAC_DISABLE_VTT;GPAC_DISABLE_OD_DUMP;_DEBUG;_CONSOLE;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_WARNINGS;GPAC_DISABLE_REMOTERY;GPAC_DISABLE_ZLIB;GPAC_HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -461,7 +462,7 @@
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>avcodec.lib;
<AdditionalDependencies>ccx_rust.lib;UserEnv.lib;avcodec.lib;
avformat.lib;
avutil.lib;
swscale.lib;WS2_32.Lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -483,7 +484,7 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../src/thirdparty/protobuf-c;../src/thirdparty/win_spec_incld;../src/thirdparty/gpacmp4;../src/thirdparty/libpng;../src/thirdparty/zlib;../src;../src/lib_ccx;../src/lib_ccx/zvbi;../src/thirdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src;../src/thirdparty/protobuf-c;../src/thirdparty/win_spec_incld;../src/thirdparty/gpacmp4;../src/thirdparty/libpng;../src/thirdparty/zlib;../src;../src/lib_ccx;../src/lib_ccx/zvbi;../src/thirdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;FT2_BUILD_LIBRARY;GPAC_DISABLE_VTT;GPAC_DISABLE_OD_DUMP;_DEBUG;_CONSOLE;_FILE_OFFSET_BITS=64;GPAC_DISABLE_REMOTERY;GPAC_DISABLE_ZLIB;GPAC_HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@@ -493,16 +494,19 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>WS2_32.Lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ccx_rust.lib;UserEnv.lib;WS2_32.Lib;%(AdditionalDependencies)</AdditionalDependencies>
<ShowProgress>NotSet</ShowProgress>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
</Link>
<PreBuildEvent>
<Command>call rust.bat</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Full|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src\thirdparty\win_spec_incld;..\src\lib_ccx;..\src\thirdparty\lib_hash;..\src\lib_ccx\zvbi;..\src\thirdparty\protobuf-c;..\src\thirdparty\gpacmp4;..\src\thirdparty\win_iconv;..\src\thirdparty\zlib;..\src\thirdparty\;..\src\thirdparty\libpng;..\src;libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src;.\libs\lib\ffmpeg-lib;..\src\thirdparty\win_spec_incld;..\src\lib_ccx;..\src\thirdparty\lib_hash;..\src\lib_ccx\zvbi;..\src\thirdparty\protobuf-c;..\src\thirdparty\gpacmp4;..\src\thirdparty\win_iconv;..\src\thirdparty\zlib;..\src\thirdparty\;..\src\thirdparty\libpng;..\src;libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>SEGMENT_BY_FILE_TIME;ENABLE_HARDSUBX;FT2_BUILD_LIBRARY;GPAC_DISABLE_VTT;GPAC_DISABLE_OD_DUMP;ENABLE_OCR;WIN32;_DEBUG;_CONSOLE;_FILE_OFFSET_BITS=64;GPAC_DISABLE_REMOTERY;GPAC_DISABLE_ZLIB;GPAC_HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -517,7 +521,7 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir
<DisableSpecificWarnings>4005;4996</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalDependencies>Ws2_32.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.danbloomberg.leptonica-1.74.0.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.google.tesseract.tesseract-master.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.gif-5.1.4.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.tiff-4.0.7.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.jpeg-9.2.0.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.openjpeg.openjp2-2.1.2.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.mgk25.jbig.jbig-2.1.0.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.mgk25.jbig.ar-2.1.0.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.xz_utils.lzma-5.2.2.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.webp-0.5.1.lib;$(ProjectDir)libs\lib\ffmpeg-lib\avcodec.lib;$(ProjectDir)libs\lib\ffmpeg-lib\avformat.lib;$(ProjectDir)libs\lib\ffmpeg-lib\avutil.lib;$(ProjectDir)libs\lib\ffmpeg-lib\swscale.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ccx_rust.lib;UserEnv.lib;Ws2_32.lib;avcodec_x32.lib;avformat_x32.lib;avutil_x32.lib;swscale_x32.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.danbloomberg.leptonica-1.74.0.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.google.tesseract.tesseract-master.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.gif-5.1.4.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.tiff-4.0.7.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.jpeg-9.2.0.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.openjpeg.openjp2-2.1.2.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.mgk25.jbig.jbig-2.1.0.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.mgk25.jbig.ar-2.1.0.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.xz_utils.lzma-5.2.2.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.webp-0.5.1.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ShowProgress>NotSet</ShowProgress>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
@@ -526,6 +530,9 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>$(ProjectDir)libs\lib\ffmpeg-lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PreBuildEvent>
<Command>call rustx86.bat</Command>
</PreBuildEvent>
<PostBuildEvent>
<Command>xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\avcodec-57.dll" "$(ProjectDir)$(OutDir)"
xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\avformat-57.dll" "$(ProjectDir)$(OutDir)"
@@ -540,7 +547,7 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Full|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../src/thirdparty/protobuf-c;../src/thirdparty/win_spec_incld;../src/thirdparty/gpacmp4;../src/thirdparty/libpng;../src/thirdparty/zlib;../src;../src/lib_ccx;../src/lib_ccx/zvbi;../src/thirdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src;.\libs\lib\ffmpeg-lib;../src/thirdparty/protobuf-c;../src/thirdparty/win_spec_incld;../src/thirdparty/gpacmp4;../src/thirdparty/libpng;../src/thirdparty/zlib;../src;../src/lib_ccx;../src/lib_ccx/zvbi;../src/thirdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>ENABLE_OCR;FT2_BUILD_LIBRARY;GPAC_DISABLE_VTT;GPAC_DISABLE_OD_DUMP;WIN32;_DEBUG;_CONSOLE;_FILE_OFFSET_BITS=64;GPAC_DISABLE_REMOTERY;GPAC_DISABLE_ZLIB;GPAC_HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@@ -550,10 +557,11 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>WS2_32.Lib;avcodec.lib;avformat.lib;avutil.lib;swscale.lib;liblept172.lib;libtesseract304d.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ccx_rust.lib;UserEnv.lib;WS2_32.Lib;avcodec.lib;avformat.lib;avutil.lib;swscale.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.danbloomberg.leptonica-1.74.0.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.google.tesseract.tesseract-master.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.gif-5.1.4.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ShowProgress>NotSet</ShowProgress>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<AdditionalLibraryDirectories>.\libs\lib\ffmpeg-lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y "$(ProjectDir)libs\lib\liblept172.dll" "$(ProjectDir)$(OutDir)"
@@ -563,7 +571,7 @@ xcopy /y "$(ProjectDir)libs\lib\libtesseract304d.dll" "$(ProjectDir)$(OutDir)"</
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Full|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src\thirdparty\win_spec_incld;..\src\lib_ccx;..\src\thirdparty\lib_hash;..\src\lib_ccx\zvbi;..\src\thirdparty\protobuf-c;..\src\thirdparty\gpacmp4;..\src\thirdparty\win_iconv;..\src\thirdparty\zlib;..\src\thirdparty\;..\src\thirdparty\libpng;..\src;libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src;.\libs\lib\ffmpeg-lib;..\src\thirdparty\win_spec_incld;..\src\lib_ccx;..\src\thirdparty\lib_hash;..\src\lib_ccx\zvbi;..\src\thirdparty\protobuf-c;..\src\thirdparty\gpacmp4;..\src\thirdparty\win_iconv;..\src\thirdparty\zlib;..\src\thirdparty\;..\src\thirdparty\libpng;..\src;libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>ENABLE_HARDSUBX;FT2_BUILD_LIBRARY;GPAC_DISABLE_VTT;GPAC_DISABLE_OD_DUMP;VERSION_FILE_PRESENT;ENABLE_OCR;WIN32;NDEBUG;_CONSOLE;_FILE_OFFSET_BITS=64;GPAC_DISABLE_REMOTERY;GPAC_DISABLE_ZLIB;GPAC_HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
@@ -575,7 +583,7 @@ xcopy /y "$(ProjectDir)libs\lib\libtesseract304d.dll" "$(ProjectDir)$(OutDir)"</
<DisableSpecificWarnings>4005;4996</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalDependencies>Ws2_32.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.danbloomberg.leptonica-1.74.0.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.google.tesseract.tesseract-master.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.gif-5.1.4.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.tiff-4.0.7.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.jpeg-9.2.0.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.openjpeg.openjp2-2.1.2.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.mgk25.jbig.jbig-2.1.0.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.mgk25.jbig.ar-2.1.0.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.xz_utils.lzma-5.2.2.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.webp-0.5.1.lib;$(ProjectDir)libs\lib\ffmpeg-lib\avcodec.lib;$(ProjectDir)libs\lib\ffmpeg-lib\avformat.lib;$(ProjectDir)libs\lib\ffmpeg-lib\avutil.lib;$(ProjectDir)libs\lib\ffmpeg-lib\swscale.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ccx_rust.lib;UserEnv.lib;Ws2_32.lib;$(ProjectDir)libs\lib\ffmpeg-lib\avcodec_x32.lib;$(ProjectDir)libs\lib\ffmpeg-lib\avformat_x32.lib;$(ProjectDir)libs\lib\ffmpeg-lib\avutil_x32.lib;$(ProjectDir)libs\lib\ffmpeg-lib\swscale_x32.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.danbloomberg.leptonica-1.74.0.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.google.tesseract.tesseract-master.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.gif-5.1.4.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.tiff-4.0.7.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.jpeg-9.2.0.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.openjpeg.openjp2-2.1.2.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.mgk25.jbig.jbig-2.1.0.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.mgk25.jbig.ar-2.1.0.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.xz_utils.lzma-5.2.2.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.webp-0.5.1.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
@@ -591,7 +599,8 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swresample-2.dll" "$(ProjectDir)$(Out
xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir)"</Command>
</PostBuildEvent>
<PreBuildEvent>
<Command>pre-build.bat</Command>
<Command>call pre-build.bat
call rustx86.bat</Command>
</PreBuildEvent>
<ProjectReference>
<LinkLibraryDependencies>false</LinkLibraryDependencies>
@@ -600,8 +609,8 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Full|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../src/thirdparty/protobuf-c;../src/thirdparty/win_spec_incld;../src/thirdparty/gpacmp4;../src/thirdparty/libpng;../src/thirdparty/zlib;../src;../src/lib_ccx;../src/lib_ccx/zvbi;../src/thirdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>VERSION_FILE_PRESENT;ENABLE_OCR;WIN32;NDEBUG;_CONSOLE;_FILE_OFFSET_BITS=64;GPAC_DISABLE_REMOTERY;GPAC_DISABLE_ZLIB;GPAC_HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src;.\libs\lib\ffmpeg-lib;../src/thirdparty/protobuf-c;../src/thirdparty/win_spec_incld;../src/thirdparty/gpacmp4;../src/thirdparty/libpng;../src/thirdparty/zlib;../src;../src/lib_ccx;../src/lib_ccx/zvbi;../src/thirdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>VERSION_FILE_PRESENT;FT2_BUILD_LIBRARY;ENABLE_OCR;WIN32;NDEBUG;_CONSOLE;_FILE_OFFSET_BITS=64;GPAC_DISABLE_REMOTERY;GPAC_DISABLE_ZLIB;GPAC_HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
@@ -609,12 +618,16 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>WS2_32.Lib;avcodec.lib;avformat.lib;avutil.lib;swscale.lib;liblept172.lib;libtesseract304d.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ccx_rust.lib;UserEnv.lib;WS2_32.Lib;avcodec.lib;avformat.lib;avutil.lib;swscale.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.danbloomberg.leptonica-1.74.0.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.google.tesseract.tesseract-master.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.gif-5.1.4.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<AdditionalLibraryDirectories>$(ProjectDir)libs\lib\ffmpeg-lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PreBuildEvent>
<Command>call pre-build.bat</Command>
</PreBuildEvent>
<PostBuildEvent>
<Command>xcopy /y "$(ProjectDir)libs\lib\liblept172.dll" "$(ProjectDir)$(OutDir)"
xcopy /y "$(ProjectDir)libs\lib\libtesseract304d.dll" "$(ProjectDir)$(OutDir)"</Command>
@@ -622,7 +635,7 @@ xcopy /y "$(ProjectDir)libs\lib\libtesseract304d.dll" "$(ProjectDir)$(OutDir)"</
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src\thirdparty\win_spec_incld;..\src\lib_ccx;..\src\thirdparty\lib_hash;..\src\lib_ccx\zvbi;..\src\thirdparty\protobuf-c;..\src\thirdparty\gpacmp4;..\src\thirdparty\win_iconv;..\src\thirdparty\zlib;..\src\thirdparty\libpng;..\src\thirdparty;..\src;libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src;..\src\thirdparty\win_spec_incld;..\src\lib_ccx;..\src\thirdparty\lib_hash;..\src\lib_ccx\zvbi;..\src\thirdparty\protobuf-c;..\src\thirdparty\gpacmp4;..\src\thirdparty\win_iconv;..\src\thirdparty\zlib;..\src\thirdparty\libpng;..\src\thirdparty;..\src;libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>VERSION_FILE_PRESENT;FT2_BUILD_LIBRARY;GPAC_DISABLE_VTT;GPAC_DISABLE_OD_DUMP;WIN32;NDEBUG;_CONSOLE;_FILE_OFFSET_BITS=64;GPAC_DISABLE_REMOTERY;GPAC_DISABLE_ZLIB;GPAC_HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader />
@@ -632,7 +645,7 @@ xcopy /y "$(ProjectDir)libs\lib\libtesseract304d.dll" "$(ProjectDir)$(OutDir)"</
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
</ClCompile>
<Link>
<AdditionalDependencies>avcodec.lib;avformat.lib;avutil.lib;swscale.lib;WS2_32.Lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ccx_rust.lib;UserEnv.lib;avcodec.lib;avformat.lib;avutil.lib;swscale.lib;WS2_32.Lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
@@ -642,7 +655,7 @@ xcopy /y "$(ProjectDir)libs\lib\libtesseract304d.dll" "$(ProjectDir)$(OutDir)"</
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
<PreBuildEvent>
<Command>pre-build.bat</Command>
<Command>call pre-build.bat</Command>
</PreBuildEvent>
<PostBuildEvent>
<Command>xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\avcodec-57.dll" "$(ProjectDir)$(OutDir)"
@@ -654,7 +667,7 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;../src/thirdparty/protobuf-c;../src/thirdparty/win_spec_incld;../src/lib_ccx;../src/thirdparty/lib_hash;../src/thirdparty/gpacmp4;../src/thirdparty/libpng;../src/thirdparty/zlib;../src/lib_ccx/zvbi;../src/thirdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src;../src/thirdparty/protobuf-c;../src/thirdparty/win_spec_incld;../src/lib_ccx;../src/thirdparty/lib_hash;../src/thirdparty/gpacmp4;../src/thirdparty/libpng;../src/thirdparty/zlib;../src/lib_ccx/zvbi;../src/thirdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>VERSION_FILE_PRESENT;FT2_BUILD_LIBRARY;GPAC_DISABLE_VTT;GPAC_DISABLE_OD_DUMP;WIN32;NDEBUG;_CONSOLE;_FILE_OFFSET_BITS=64;GPAC_DISABLE_REMOTERY;GPAC_DISABLE_ZLIB;GPAC_HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader>
@@ -663,17 +676,18 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>WS2_32.Lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ccx_rust.lib;UserEnv.lib;WS2_32.Lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
</Link>
<PreBuildEvent>
<Command>pre-build.bat</Command>
<Command>call pre-build.bat
call rust.bat </Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@@ -333,30 +333,6 @@
<ClInclude Include="..\src\thirdparty\zlib\zutil.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thirdparty\zvbi\bcd.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thirdparty\zvbi\bit_slicer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thirdparty\zvbi\macros.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thirdparty\zvbi\misc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thirdparty\zvbi\raw_decoder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thirdparty\zvbi\sampling_par.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thirdparty\zvbi\sliced.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thirdparty\zvbi\zvbi_decoder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thirdparty\win_spec_incld\inttypes.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -381,6 +357,30 @@
<ClInclude Include="..\src\thirdparty\freetype\include\freetype\config\ftstdlib.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\lib_ccx\zvbi\bcd.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\lib_ccx\zvbi\bit_slicer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\lib_ccx\zvbi\macros.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\lib_ccx\zvbi\misc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\lib_ccx\zvbi\raw_decoder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\lib_ccx\zvbi\sampling_par.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\lib_ccx\zvbi\sliced.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\lib_ccx\zvbi\zvbi_decoder.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\ccextractor.c">
@@ -704,9 +704,6 @@
<ClCompile Include="..\src\thirdparty\gpacmp4\movie_fragments.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\thirdparty\gpacmp4\mp4.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\thirdparty\gpacmp4\odf_code.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -833,18 +830,6 @@
<ClCompile Include="..\src\thirdparty\zlib\zutil.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\thirdparty\zvbi\bit_slicer.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\thirdparty\zvbi\decoder.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\thirdparty\zvbi\raw_decoder.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\thirdparty\zvbi\sampling_par.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\thirdparty\freetype\autofit\autofit.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -959,10 +944,40 @@
<ClCompile Include="..\src\thirdparty\zlib\adler32.c">
<Filter>Source Files\zlib</Filter>
</ClCompile>
<ClCompile Include="..\src\lib_ccx\mp4.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\thirdparty\gpacmp4\os_thread.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\thirdparty\gpacmp4\module.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\thirdparty\gpacmp4\os_module.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\thirdparty\gpacmp4\xml_parser.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\thirdparty\gpacmp4\constants.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\lib_ccx\zvbi\bit_slicer.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\lib_ccx\zvbi\decoder.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\lib_ccx\zvbi\raw_decoder.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\lib_ccx\zvbi\sampling_par.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\src\lib_ccx\ccx_sub_entry_message.proto">
<Filter>Header Files\lib_ccx</Filter>
</None>
</ItemGroup>
</Project>
</Project>

183
windows/installer.wxs Normal file
View File

@@ -0,0 +1,183 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<Package Name="CCExtractor" Language="1033" Version="$(AppVersion)" Manufacturer="CCExtractor development" UpgradeCode="e70dbe37-bb04-4c39-bedc-966a6b073bcf" InstallerVersion="200">
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed."/>
<MediaTemplate EmbedCab="yes"/>
<Feature Id="CCX" Title="CCExtractor Setup" Level="1">
<ComponentGroupRef Id="CCX_Components_MainFolder"/>
<ComponentGroupRef Id="CCX_Components_MainFolder_data"/>
<ComponentGroupRef Id="CCX_Components_MainFolder_data_flutter_assets"/>
<ComponentGroupRef Id="CCX_Components_MainFolder_data_flutter_assets_assets"/>
<ComponentGroupRef Id="CCX_Components_MainFolder_data_flutter_assets_fonts"/>
<ComponentGroupRef Id="CCX_Components_MainFolder_data_flutter_assets_cupertino"/>
<ComponentRef Id="ApplicationShortcutDesktop"/>
</Feature>
<Icon Id="ccxgui.exe" SourceFile="./installer/ccxgui.exe"/>
<!-- Derives from the regular install dir, but skips the license dialog. -->
<UI Id="WixUI_InstallDir">
<TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
<TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
<TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
<Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
<Property Id="WixUI_Mode" Value="InstallDir" />
<DialogRef Id="BrowseDlg" />
<DialogRef Id="DiskCostDlg" />
<DialogRef Id="ErrorDlg" />
<DialogRef Id="FatalError" />
<DialogRef Id="FilesInUse" />
<DialogRef Id="MsiRMFilesInUse" />
<DialogRef Id="PrepareDlg" />
<DialogRef Id="ProgressDlg" />
<DialogRef Id="ResumeDlg" />
<DialogRef Id="UserExit" />
<Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath" Order="3" />
<Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog" Value="InvalidDirDlg" Order="4" Condition="NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID&lt;&gt;&quot;1&quot;" />
<Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999" />
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg" Condition="NOT Installed" />
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Condition="Installed AND PATCH" />
<Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" />
<Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1" />
<Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath" Order="2" Condition="NOT WIXUI_DONTVALIDATEPATH" />
<Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog" Value="InvalidDirDlg" Order="3" Condition="NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID&lt;&gt;&quot;1&quot;" />
<Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="4" Condition="WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID=&quot;1&quot;" />
<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1" />
<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2" />
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg" Order="1" Condition="NOT Installed" />
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2" Condition="Installed AND NOT PATCH" />
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2" Condition="Installed AND PATCH" />
<Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg" />
<Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg" />
<Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg" />
<Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg" />
<Property Id="ARPNOMODIFY" Value="1" />
</UI>
<UIRef Id="WixUI_Common" />
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER"/>
</Package>
<Fragment>
<Directory Id="DesktopFolder" Name="Desktop">
<Component Id="ApplicationShortcutDesktop" Guid="*">
<Shortcut Id="ApplicationDesktopShortcut"
Name="CCExtractor"
Description="Run CCExtractor"
Target="[INSTALLFOLDER]ccxgui.exe"
WorkingDirectory="INSTALLFOLDER"/>
<RemoveFolder Id="DesktopFolder" On="uninstall"/>
<RegistryValue
Root="HKCU"
Key="Software\CCExtractor\ccextractor"
Name="installed"
Type="integer"
Value="1"
KeyPath="yes"/>
</Component>
</Directory>
<StandardDirectory Id="ProgramFiles6432Folder">
<Directory Id="INSTALLFOLDER" Name="CCExtractor">
<Directory Id="CCX_data" Name="data">
<Directory Id="CCX_data_flutter_assets" Name="flutter_assets">
<Directory Id="CCX_data_flutter_assets_assets" Name="assets"/>
<Directory Id="CCX_data_flutter_assets_fonts" Name="fonts"/>
<Directory Id="dirEE44DD2D485FE70BEAFB55755745AB6E" Name="packages">
<Directory Id="dir382F01892F72FB688A688BE6E01B93A3" Name="cupertino_icons">
<Directory Id="CCX_data_flutter_assets_cupertino" Name="assets"/>
</Directory>
</Directory>
</Directory>
</Directory>
</Directory>
</StandardDirectory>
</Fragment>
<Fragment>
<ComponentGroup Id="CCX_Components_MainFolder" Directory="INSTALLFOLDER">
<Component Guid="{2D6CDFAD-A645-4929-9518-B43788B9E5F3}">
<File Id="CCX_Full_executable" Source="./installer/ccextractorwinfull.exe" KeyPath="yes"/>
</Component>
<Component Guid="{5DA8F5F9-922B-45E1-B0A9-CB241996D9EE}">
<File Id="CCX_avcodec" Source="./installer/avcodec-57.dll" KeyPath="yes"/>
</Component>
<Component Guid="{00E5F91A-D4D9-4A3D-B498-1CF45D18770F}">
<File Id="CCX_avformat" Source="./installer/avformat-57.dll" KeyPath="yes"/>
</Component>
<Component Guid="{AA5FE610-7566-483C-84D0-70B0435E08B0}">
<File Id="CCX_avutil" Source="./installer/avutil-55.dll" KeyPath="yes"/>
</Component>
<Component Guid="{334ABDD6-FDBB-41EB-87FE-DAD3295DAE2D}">
<File Id="CCX_swresample" Source="./installer/swresample-2.dll" KeyPath="yes"/>
</Component>
<Component Guid="{888B47CF-0377-490A-8B7E-341D2C71EAD0}">
<File Id="CCX_swscale" Source="./installer/swscale-4.dll" KeyPath="yes"/>
</Component>
<Component Guid="{8B69210B-5091-4C63-8902-E0ADDBE2C080}">
<File Source="./installer/ccxgui.exe" KeyPath="yes"/>
</Component>
<Component Guid="{1B37F14A-3BA6-4837-8A6F-6EA01A25DA26}">
<File Source="./installer/file_selector_windows_plugin.dll" KeyPath="yes"/>
</Component>
<Component Guid="{B276C96D-9737-4B8C-B55B-60F392DED331}">
<File Source="./installer/url_launcher_windows_plugin.dll" KeyPath="yes"/>
</Component>
<Component Guid="{4B627AA9-55DD-40ED-99F9-54F67EC73887}">
<File Source="./installer/flutter_windows.dll" KeyPath="yes"/>
</Component>
<Component Guid="{32F0A64B-0C07-4807-A48C-714B2533A03C}">
<File Source="./installer/msvcp140.dll" KeyPath="yes"/>
</Component>
<Component Guid="{8425DEB5-8CF4-4672-AE45-561CF76B2072}">
<File Source="./installer/vcruntime140.dll" KeyPath="yes"/>
</Component>
<Component Guid="{1F3DBC7E-25D5-441D-9B41-96C33FEA5157}">
<File Source="./installer/vcruntime140_1.dll" KeyPath="yes"/>
</Component>
<Component Guid="{BE7FE765-EBA8-4FAB-8864-8561C50D39CF}">
<File Source="./installer/window_size_plugin.dll" KeyPath="yes"/>
</Component>
</ComponentGroup>
<ComponentGroup Id="CCX_Components_MainFolder_data" Directory="CCX_data">
<Component Id="cmp205CD51FCB7438CA9DDF9D318D5BDD93" Guid="{50D63F41-6529-4009-9092-F4D5B60DDF1B}">
<File Id="filBBF0A8ED8BF5DEEA3D5FE3E0B96C18FF" KeyPath="yes" Source="./installer/data/app.so"/>
</Component>
<Component Id="cmp3BB4C81F1F7BAB8E1AEB858EBC85CC1E" Guid="{88E94229-FBE7-4DC8-B9E2-B5E27FFB844C}">
<File Id="fil3F969272E8EAC0F75CC6D464590D2FBE" KeyPath="yes" Source="./installer/data/icudtl.dat"/>
</Component>
</ComponentGroup>
<ComponentGroup Id="CCX_Components_MainFolder_data_flutter_assets" Directory="CCX_data_flutter_assets">
<Component Id="cmp1C63471C238EEA92D0AE37BC7DF9E605" Guid="{DEAF277D-3D05-4B37-A732-9514B503B74A}">
<File Id="fil3F43BEEF0A85EE6619E4674CA43CB616" KeyPath="yes" Source="./installer/data/flutter_assets/AssetManifest.json"/>
</Component>
<Component Id="cmp414DC13EF11DED7194619DD3FC5F4CA7" Guid="{E66832FA-6880-4249-92A0-A26A4FF0A1F9}">
<File Id="filD6CD37343140A4FABEA77420A8B86B57" KeyPath="yes" Source="./installer/data/flutter_assets/FontManifest.json"/>
</Component>
<Component Id="cmp4AD05995360EA9B961C2D73FE38274D2" Guid="{B09977A1-1C36-4F5D-B3BC-394D10AC950D}">
<File Id="filC4871B1F6646D8021500E7E62CF93FAC" KeyPath="yes" Source="./installer/data/flutter_assets/NOTICES.Z"/>
</Component>
</ComponentGroup>
<ComponentGroup Id="CCX_Components_MainFolder_data_flutter_assets_assets" Directory="CCX_data_flutter_assets_assets">
<Component Id="cmp5F6AEEA1DB53EC5D0D51921A0B62098C" Guid="{CECCAC58-B818-42E2-849A-BFA4A8CA4FBE}">
<File Id="fil0E47318EAF44F6EEF60A89C92FCD2FAA" KeyPath="yes" Source="./installer/data/flutter_assets/assets/ccextractor"/>
</Component>
<Component Id="cmpDA8A6D10314F9C5A931AB86118A106CC" Guid="{75DE9E26-1024-4E83-8995-078624187483}">
<File Id="fil72BB9315DC954394F9980ECD2DA6D21F" KeyPath="yes" Source="./installer/data/flutter_assets/assets/ccx.svg"/>
</Component>
</ComponentGroup>
<ComponentGroup Id="CCX_Components_MainFolder_data_flutter_assets_fonts" Directory="CCX_data_flutter_assets_fonts">
<Component Id="cmp97B1795B6861175BEF48B71FC703EDA6" Guid="{292269F8-9FC7-464A-A9AB-AF5BA97D7F06}">
<File Id="fil26D47F100D1B90F2759D0EAE797393FC" KeyPath="yes" Source="./installer/data/flutter_assets/fonts/MaterialIcons-Regular.otf"/>
</Component>
</ComponentGroup>
<ComponentGroup Id="CCX_Components_MainFolder_data_flutter_assets_cupertino" Directory="CCX_data_flutter_assets_cupertino">
<Component Id="cmp18EDD5C842814546AE2A43759CD36C77" Guid="{30AFB9BB-1C7D-4CDB-ADCA-D0773F152B45}">
<File Id="fil341334402AF57DB92DF3F7C92E983317" KeyPath="yes" Source="./installer/data/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf"/>
</Component>
</ComponentGroup>
</Fragment>
</Wix>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

6
windows/rust.bat Normal file
View File

@@ -0,0 +1,6 @@
for /f "delims=" %%i in ('cd') do set output=%%i
set CARGO_TARGET_DIR=%output%
cd ..\src\rust
cargo build
cd ..\..\windows
copy debug\ccx_rust.lib .\ccx_rust.lib

6
windows/rustx86.bat Normal file
View File

@@ -0,0 +1,6 @@
for /f "delims=" %%i in ('cd') do set output=%%i
set CARGO_TARGET_DIR=%output%
cd ..\src\rust
cargo build --target=i686-pc-windows-msvc
cd ..\..\windows
copy i686-pc-windows-msvc\debug\ccx_rust.lib .\ccx_rust.lib