Compare commits

..

10 commits

Author SHA1 Message Date
GitHub Actions
4d21a05d80 Update CImg to v.3.3.6 2024-06-03 00:28:47 +00:00
GitHub Actions
a5b9c64c7a Update CImg to v.3.3.5 2024-04-17 20:26:24 +00:00
Aaron Liu
56bac07109
try checkoutv2 per https://github.com/actions/checkout/issues/664 2024-04-02 22:22:36 -04:00
Quentin Santos
92cf12d2ec Fix some minor typos 2024-03-23 10:36:25 +01:00
Aaron Liu
84a3616796
fix entry point display and remove spurious newlines 2024-03-20 16:29:33 -04:00
Stefan Haustein
38ec4249b8 small fixes 2024-03-20 20:59:16 +01:00
Stefan Haustein
df32d7e1c1 Updated README, pointing at the API. 2024-03-20 20:14:42 +01:00
Stefan Haustein
8aca9afaf7 cleanup / formatting 2024-03-06 18:51:31 +01:00
Stefan Haustein
917b381bc3 preparation for more character groups 2024-03-06 18:37:16 +01:00
GitHub Actions
a18c4e62c6 Update CImg to v.3.3.4 2024-03-03 00:27:09 +00:00
5 changed files with 1595 additions and 1184 deletions

View file

@ -23,9 +23,9 @@ jobs:
name: Update CImg.h
runs-on: ubuntu-latest
needs: check-version
if: ${{ needs.check-version.outputs.latest-tag != 'v.3.3.3' }}
if: ${{ needs.check-version.outputs.latest-tag != 'v.3.3.6' }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
name: Checkout this repository
with:
token: ${{ secrets.CIMG_UPDATE_TOKEN }}
@ -36,7 +36,7 @@ jobs:
location: 'src'
- name: Commit new CImg version (and update script)
run: |
sed -i 's/v.3.3.3/${{ needs.check-version.outputs.latest-tag }}/' .github/workflows/cimg.yml
sed -i 's/v.3.3.6/${{ needs.check-version.outputs.latest-tag }}/' .github/workflows/cimg.yml
git config user.name 'GitHub Actions'
git config user.email 'actions@github.com'
git commit -am "Update CImg to ${{ needs.check-version.outputs.latest-tag }}"

View file

@ -21,11 +21,13 @@ The shell will expand wildcards. By default, thumbnails and file names will be d
## News
- 2020-10-22: The Java version is now **deprecated**. Development has long shifted to the C++ version since that was created, and the last meaningful update to it was in 2016.
- 2021-05-22: We now support Apple Clang, thanks to the C++ filesystem library being no longer experimental. Issue forms have also been added to the GitHub repository.
- 2023-09-29: Today marks the 40th anniversary of the GNU project. If you haven't learned the news concerning it and Stallman, please do. In project news, @aaronliu0130 will probably be developing this project from now on as the original author has moved on to better things to do. Support for MSVC has been added and the repository is now under an Apache 2.0 or GPL3 dual license. CI building for each release will hopefully be setup soon. The main program has also adopted a mostly Google code-style because I (aaron) think it simply makes sense.
- 2024-03-20: Added a section on how to use the API.
- 2024-02-01: We are currently working on splitting the source code into dependency-free library files and a client that uses CImg.
- 2023-09-29: Today marks the 40th anniversary of the GNU project. If you haven't learned the news concerning it and Stallman, please do.
Support for MSVC has been added and the repository is now under an Apache 2.0 or GPL3 dual license. CI building for each release will hopefully be setup soon. The main program has also adopted a mostly Google code-style because I (aaron) think it simply makes sense.
`SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later`
- 2024-02-01: We are currently working on splitting the source code into library-agnostic library files and a client that uses CImg.
- 2021-05-22: We now support Apple Clang, thanks to the C++ filesystem library being no longer experimental. Issue forms have also been added to the GitHub repository.
- 2020-10-22: The Java version is now **deprecated**. Development has long shifted to the C++ version since that was created, and the last meaningful update to it was in 2016.
## Installation
@ -45,18 +47,55 @@ make
sudo make install
```
### Mac: Homebrew
Please don't forget to install ImageMagick... On Debian based Linux via `sudo apt install imagemagick` and
on MacOS via `brew install imagemagick`.
### Mac: Homebrew
```sh
brew install tiv
```
As the original Apple Shell only supports 256 color mode (-256) and there seems to be some extra
line spacing, distorting the image, we also recommend installing iTerm2:
```
brew install --cask iterm2
```
### Third-Party Packages
- @megamaced has created [an RPM for SUSE](https://build.opensuse.org/package/show/home:megamaced/terminalimageviewer)
- @bperel has created [a Docker image](https://hub.docker.com/r/bperel/terminalimageviewer)
## Common problems / Troubleshooting
- Errors such as "unrecognized file format"? Make sure ImageMagic is installed.
- On some linux platforms, an extra flag seems to be required: `make LDLIBS=-lstdc++fs` (but it also breaks MacOs), see <https://github.com/stefanhaustein/TerminalImageViewer/issues/103>
- If you see strange horizontal lines, the characters don't fully fill the character cell. Remove additional line spacing in your terminal app
- Wrong colors? Try -256 to use a 256 color palette instead of 24 bit colors
- Strange characters? Try -0 or install an use full unicode font (e.g. inconsolata or firacode)
## Using the TIV API
Tiv can be used as an API. So if you always wanted to run your favorite FPS in a shell, this is the opportunity.
All the code useful as a library is isolated in [tiv_lib.h](https://github.com/stefanhaustein/TerminalImageViewer/blob/master/src/tiv_lib.h)
and [tiv_lib.cc](https://github.com/stefanhaustein/TerminalImageViewer/blob/master/src/tiv_lib.cc).
The main entry point is
```cpp
CharData findCharData(GetPixelFunction get_pixel, int x0, int y0, const int &flags)
```
The call takes a std::Function that allows the TIV code to request pixels from your framebuffer.
From this framebuffer, the call will query pixels for a 4x8 pixel rectangle, where x0 and y0
define the top left corner. The call searches the best unicode graphics character and colors to approximate this
cell of the image, and returns these in a CharData struct.
## Contributions
- 2019-03-26: Exciting week: @cabelo has fixed output redirection, @boretom has added cross-compilation support to the build file and @AlanDeSmet has fixed tall thumbnails and greyscale images.
@ -69,14 +108,6 @@ I am happy to accept useful contributions under the Apache 2.0 license, but...
- This program currently only depends on CImg and ImageMagick as image processing libraries and I'd prefer to keep it that way.
- Support for additional platforms, CPUs or similar will require somebody who is happy to help with maintenance, in particular if I don't have access to it.
## Common problems / Troubleshooting
- Errors such as "unrecognized file format"? Make sure ImageMagic is installed.
- On some linux platforms, an extra flag seems to be required: `make LDLIBS=-lstdc++fs` (but it also breaks MacOs), see <https://github.com/stefanhaustein/TerminalImageViewer/issues/103>
- If you see strange horizontal lines, the characters don't fully fill the character cell. Remove additional line spacing in your terminal app
- Wrong colors? Try -256 to use a 256 color palette instead of 24 bit colors
- Strange characters? Try -0 or install an use full unicode font (e.g. inconsolata or firacode)
## Examples
Most examples were shot with the Java version of this program, which should have equivalent output but slower by millenia in CPU years.

2496
src/CImg.h

File diff suppressed because it is too large Load diff

View file

@ -200,7 +200,7 @@ usage: tiv [options] <image> [<image>...]
-0 : No block character adjustment, always use top half block char.
-2, --256 : Use 256-bit colors. Needed to display properly on macOS Terminal.
-c <num> : Number of thumbnail columns in 'dir' mode (3 by default).
-d, --dir : Force 'dir' mode. Automatially selected for more than one input.
-d, --dir : Force 'dir' mode. Automatically selected for more than one input.
-f, --full: Force 'full' mode. Automatically selected for one input.
--help : Display this help text.
-h <num> : Set the maximum output height to <num> lines.
@ -216,7 +216,7 @@ int main(int argc, char *argv[]) {
bool detectSize = true;
// Platform-specific implementations for determining console size, better
// implementations are welcome Fallback sizes when unsuccesful
// implementations are welcome Fallback sizes when unsuccessful
int maxWidth = 80;
int maxHeight = 24;
@ -307,7 +307,7 @@ int main(int argc, char *argv[]) {
CONSOLE_SCREEN_BUFFER_INFO w;
if (GetConsoleScreenBufferInfo(
GetStdHandle(STD_OUTPUT_HANDLE),
&w)) { // just like powershell, but without the hyphens, hooray
&w)) { // just like PowerShell, but without the hyphens, hooray
maxWidth = w.dwSize.X * 4;
maxHeight = w.dwSize.Y * 8;
} else {
@ -334,7 +334,7 @@ int main(int argc, char *argv[]) {
image.resize(new_size.width, new_size.height, -100, -100,
5);
}
// the acutal magic which generates the output
// the actual magic which generates the output
printImage(image, flags);
} catch (cimg_library::CImgIOException &e) {
std::cerr << "Error: '" << filename

View file

@ -43,129 +43,169 @@
#include <string>
#include <vector>
const int END_MARKER = 0;
// An interleaved map of 4x8 bit character bitmaps (each hex digit represents a
// row) to the corresponding unicode character code point.
// row) to the corresponding Unicode character code point.
constexpr unsigned int BITMAPS[] = {
0x00000000, 0x00a0,
0x00000000, 0x00a0, 0,
// Block graphics
// 0xffff0000, 0x2580, // upper 1/2; redundant with inverse lower 1/2
// 0xffff0000, 0x2580, 0, // upper 1/2; redundant with inverse lower 1/2
0x0000000f, 0x2581, // lower 1/8
0x000000ff, 0x2582, // lower 1/4
0x00000fff, 0x2583,
0x0000ffff, 0x2584, // lower 1/2
0x000fffff, 0x2585,
0x00ffffff, 0x2586, // lower 3/4
0x0fffffff, 0x2587,
0x0000000f, 0x2581, 0, // lower 1/8
0x000000ff, 0x2582, 0, // lower 1/4
0x00000fff, 0x2583, 0,
0x0000ffff, 0x2584, 0, // lower 1/2
0x000fffff, 0x2585, 0,
0x00ffffff, 0x2586, 0, // lower 3/4
0x0fffffff, 0x2587, 0,
// 0xffffffff, 0x2588, // full; redundant with inverse space
0xeeeeeeee, 0x258a, // left 3/4
0xcccccccc, 0x258c, // left 1/2
0x88888888, 0x258e, // left 1/4
0xeeeeeeee, 0x258a, 0, // left 3/4
0xcccccccc, 0x258c, 0, // left 1/2
0x88888888, 0x258e, 0, // left 1/4
0x0000cccc, 0x2596, // quadrant lower left
0x00003333, 0x2597, // quadrant lower right
0xcccc0000, 0x2598, // quadrant upper left
0x0000cccc, 0x2596, 0, // quadrant lower left
0x00003333, 0x2597, 0, // quadrant lower right
0xcccc0000, 0x2598, 0, // quadrant upper left
// 0xccccffff, 0x2599, // 3/4 redundant with inverse 1/4
0xcccc3333, 0x259a, // diagonal 1/2
0xcccc3333, 0x259a, 0, // diagonal 1/2
// 0xffffcccc, 0x259b, // 3/4 redundant
// 0xffff3333, 0x259c, // 3/4 redundant
0x33330000, 0x259d, // quadrant upper right
0x33330000, 0x259d, 0, // quadrant upper right
// 0x3333cccc, 0x259e, // 3/4 redundant
// 0x3333ffff, 0x259f, // 3/4 redundant
// Line drawing subset: no double lines, no complex light lines
0x000ff000, 0x2501, // Heavy horizontal
0x66666666, 0x2503, // Heavy vertical
0x000ff000, 0x2501, 0, // Heavy horizontal
0x66666666, 0x2503, 0, // Heavy vertical
0x00077666, 0x250f, // Heavy down and right
0x000ee666, 0x2513, // Heavy down and left
0x66677000, 0x2517, // Heavy up and right
0x666ee000, 0x251b, // Heavy up and left
0x00077666, 0x250f, 0, // Heavy down and right
0x000ee666, 0x2513, 0, // Heavy down and left
0x66677000, 0x2517, 0, // Heavy up and right
0x666ee000, 0x251b, 0, // Heavy up and left
0x66677666, 0x2523, // Heavy vertical and right
0x666ee666, 0x252b, // Heavy vertical and left
0x000ff666, 0x2533, // Heavy down and horizontal
0x666ff000, 0x253b, // Heavy up and horizontal
0x666ff666, 0x254b, // Heavy cross
0x66677666, 0x2523, 0, // Heavy vertical and right
0x666ee666, 0x252b, 0, // Heavy vertical and left
0x000ff666, 0x2533, 0, // Heavy down and horizontal
0x666ff000, 0x253b, 0, // Heavy up and horizontal
0x666ff666, 0x254b, 0, // Heavy cross
0x000cc000, 0x2578, // Bold horizontal left
0x00066000, 0x2579, // Bold horizontal up
0x00033000, 0x257a, // Bold horizontal right
0x00066000, 0x257b, // Bold horizontal down
0x000cc000, 0x2578, 0, // Bold horizontal left
0x00066000, 0x2579, 0, // Bold horizontal up
0x00033000, 0x257a, 0, // Bold horizontal right
0x00066000, 0x257b, 0, // Bold horizontal down
0x06600660, 0x254f, // Heavy double dash vertical
0x06600660, 0x254f, 0, // Heavy double dash vertical
0x000f0000, 0x2500, // Light horizontal
0x0000f000, 0x2500, //
0x44444444, 0x2502, // Light vertical
0x22222222, 0x2502,
0x000f0000, 0x2500, 0, // Light horizontal
0x0000f000, 0x2500, 0, //
0x44444444, 0x2502, 0, // Light vertical
0x22222222, 0x2502, 0,
0x000e0000, 0x2574, // light left
0x0000e000, 0x2574, // light left
0x44440000, 0x2575, // light up
0x22220000, 0x2575, // light up
0x00030000, 0x2576, // light right
0x00003000, 0x2576, // light right
0x00004444, 0x2577, // light down
0x00002222, 0x2577, // light down
0x000e0000, 0x2574, 0, // light left
0x0000e000, 0x2574, 0, // light left
0x44440000, 0x2575, 0, // light up
0x22220000, 0x2575, 0, // light up
0x00030000, 0x2576, 0, // light right
0x00003000, 0x2576, 0, // light right
0x00004444, 0x2577, 0, // light down
0x00002222, 0x2577, 0, // light down
// Misc technical
0x44444444, 0x23a2, // [ extension
0x22222222, 0x23a5, // ] extension
0x44444444, 0x23a2, 0, // [ extension
0x22222222, 0x23a5, 0, // ] extension
0x0f000000, 0x23ba, // Horizontal scanline 1
0x00f00000, 0x23bb, // Horizontal scanline 3
0x00000f00, 0x23bc, // Horizontal scanline 7
0x000000f0, 0x23bd, // Horizontal scanline 9
0x0f000000, 0x23ba, 0, // Horizontal scanline 1
0x00f00000, 0x23bb, 0, // Horizontal scanline 3
0x00000f00, 0x23bc, 0, // Horizontal scanline 7
0x000000f0, 0x23bd, 0, // Horizontal scanline 9
// Geometrical shapes. Tricky because some of them are too wide.
// 0x00ffff00, 0x25fe, // Black medium small square
0x00066000, 0x25aa, // Black small square
// 0x00ffff00, 0x25fe, 0, // Black medium small square
0x00066000, 0x25aa, 0, // Black small square
// 0x11224488, 0x2571, // diagonals
// 0x88442211, 0x2572,
// 0x99666699, 0x2573,
// 0x000137f0, 0x25e2, // Triangles
// 0x0008cef0, 0x25e3,
// 0x000fec80, 0x25e4,
// 0x000f7310, 0x25e5,
0, 0, // End marker for "regular" characters
// 0x11224488, 0x2571, 0, // diagonals
// 0x88442211, 0x2572, 0,
// 0x99666699, 0x2573, 0,
// 0x000137f0, 0x25e2, 0, // Triangles
// 0x0008cef0, 0x25e3, 0,
// 0x000fec80, 0x25e4, 0,
// 0x000f7310, 0x25e5, 0,
// Teletext / legacy graphics 3x2 block character codes.
// Using a 3-2-3 pattern consistently, perhaps we should create automatic
// variations....
0xccc00000, 0xfb00, 0x33300000, 0xfb01, 0xfff00000, 0xfb02, 0x000cc000,
0xfb03, 0xccccc000, 0xfb04, 0x333cc000, 0xfb05, 0xfffcc000, 0xfb06,
0x00033000, 0xfb07, 0xccc33000, 0xfb08, 0x33333000, 0xfb09, 0xfff33000,
0xfb0a, 0x000ff000, 0xfb0b, 0xcccff000, 0xfb0c, 0x333ff000, 0xfb0d,
0xfffff000, 0xfb0e, 0x00000ccc, 0xfb0f,
0xccc00000, 0xfb00, FLAG_TELETEXT,
0x33300000, 0xfb01, FLAG_TELETEXT,
0xfff00000, 0xfb02, FLAG_TELETEXT,
0x000cc000, 0xfb03, FLAG_TELETEXT,
0xccccc000, 0xfb04, FLAG_TELETEXT,
0x333cc000, 0xfb05, FLAG_TELETEXT,
0xfffcc000, 0xfb06, FLAG_TELETEXT,
0x00033000, 0xfb07, FLAG_TELETEXT,
0xccc33000, 0xfb08, FLAG_TELETEXT,
0x33333000, 0xfb09, FLAG_TELETEXT,
0xfff33000, 0xfb0a, FLAG_TELETEXT,
0x000ff000, 0xfb0b, FLAG_TELETEXT,
0xcccff000, 0xfb0c, FLAG_TELETEXT,
0x333ff000, 0xfb0d, FLAG_TELETEXT,
0xfffff000, 0xfb0e, FLAG_TELETEXT,
0x00000ccc, 0xfb0f, FLAG_TELETEXT,
0xccc00ccc, 0xfb10, 0x33300ccc, 0xfb11, 0xfff00ccc, 0xfb12, 0x000ccccc,
0xfb13, 0x333ccccc, 0xfb14, 0xfffccccc, 0xfb15, 0x00033ccc, 0xfb16,
0xccc33ccc, 0xfb17, 0x33333ccc, 0xfb18, 0xfff33ccc, 0xfb19, 0x000ffccc,
0xfb1a, 0xcccffccc, 0xfb1b, 0x333ffccc, 0xfb1c, 0xfffffccc, 0xfb1d,
0x00000333, 0xfb1e, 0xccc00333, 0xfb1f,
0xccc00ccc, 0xfb10, FLAG_TELETEXT,
0x33300ccc, 0xfb11, FLAG_TELETEXT,
0xfff00ccc, 0xfb12, FLAG_TELETEXT,
0x000ccccc, 0xfb13, FLAG_TELETEXT,
0x333ccccc, 0xfb14, FLAG_TELETEXT,
0xfffccccc, 0xfb15, FLAG_TELETEXT,
0x00033ccc, 0xfb16, FLAG_TELETEXT,
0xccc33ccc, 0xfb17, FLAG_TELETEXT,
0x33333ccc, 0xfb18, FLAG_TELETEXT,
0xfff33ccc, 0xfb19, FLAG_TELETEXT,
0x000ffccc, 0xfb1a, FLAG_TELETEXT,
0xcccffccc, 0xfb1b, FLAG_TELETEXT,
0x333ffccc, 0xfb1c, FLAG_TELETEXT,
0xfffffccc, 0xfb1d, FLAG_TELETEXT,
0x00000333, 0xfb1e, FLAG_TELETEXT,
0xccc00333, 0xfb1f, FLAG_TELETEXT,
0x33300333, 0x1b20, 0xfff00333, 0x1b21, 0x000cc333, 0x1b22, 0xccccc333,
0x1b23, 0x333cc333, 0x1b24, 0xfffcc333, 0x1b25, 0x00033333, 0x1b26,
0xccc33333, 0x1b27, 0xfff33333, 0x1b28, 0x000ff333, 0x1b29, 0xcccff333,
0x1b2a, 0x333ff333, 0x1b2b, 0xfffff333, 0x1b2c, 0x00000fff, 0x1b2d,
0xccc00fff, 0x1b2e, 0x33300fff, 0x1b2f,
0x33300333, 0x1b20, FLAG_TELETEXT,
0xfff00333, 0x1b21, FLAG_TELETEXT,
0x000cc333, 0x1b22, FLAG_TELETEXT,
0xccccc333, 0x1b23, FLAG_TELETEXT,
0x333cc333, 0x1b24, FLAG_TELETEXT,
0xfffcc333, 0x1b25, FLAG_TELETEXT,
0x00033333, 0x1b26, FLAG_TELETEXT,
0xccc33333, 0x1b27, FLAG_TELETEXT,
0xfff33333, 0x1b28, FLAG_TELETEXT,
0x000ff333, 0x1b29, FLAG_TELETEXT,
0xcccff333, 0x1b2a, FLAG_TELETEXT,
0x333ff333, 0x1b2b, FLAG_TELETEXT,
0xfffff333, 0x1b2c, FLAG_TELETEXT,
0x00000fff, 0x1b2d, FLAG_TELETEXT,
0xccc00fff, 0x1b2e, FLAG_TELETEXT,
0x33300fff, 0x1b2f, FLAG_TELETEXT,
0xfff00fff, 0x1b30, 0x000ccfff, 0x1b31, 0xcccccfff, 0x1b32, 0x333ccfff,
0x1b33, 0xfffccfff, 0x1b34, 0x00033fff, 0x1b35, 0xccc33fff, 0x1b36,
0x33333fff, 0x1b37, 0xfff33fff, 0x1b38, 0x000fffff, 0x1b39, 0xcccfffff,
0x1b3a, 0x333fffff, 0x1b3b,
0xfff00fff, 0x1b30, FLAG_TELETEXT,
0x000ccfff, 0x1b31, FLAG_TELETEXT,
0xcccccfff, 0x1b32, FLAG_TELETEXT,
0x333ccfff, 0x1b33, FLAG_TELETEXT,
0xfffccfff, 0x1b34, FLAG_TELETEXT,
0x00033fff, 0x1b35, FLAG_TELETEXT,
0xccc33fff, 0x1b36, FLAG_TELETEXT,
0x33333fff, 0x1b37, FLAG_TELETEXT,
0xfff33fff, 0x1b38, FLAG_TELETEXT,
0x000fffff, 0x1b39, FLAG_TELETEXT,
0xcccfffff, 0x1b3a, FLAG_TELETEXT,
0x333fffff, 0x1b3b, FLAG_TELETEXT,
0, 1 // End marker for extended TELETEXT mode.
0, END_MARKER, 0 // End marker
};
// The channel indices are 0, 1, 2 for R, G, B
@ -302,10 +342,8 @@ CharData findCharData(GetPixelFunction get_pixel, int x0, int y0,
unsigned int best_pattern = 0x0000ffff;
int codepoint = 0x2584;
bool inverted = false;
unsigned int end_marker = flags & FLAG_TELETEXT ? 1 : 0;
for (int i = 0; BITMAPS[i + 1] != end_marker; i += 2) {
// Skip all end markers
if (BITMAPS[i + 1] < 32) {
for (int i = 0; BITMAPS[i + 1] != END_MARKER; i += 3) {
if ((BITMAPS[i + 2] & flags) != BITMAPS[i + 2]) {
continue;
}
unsigned int pattern = BITMAPS[i];