1 /*
2  * Copyright (C) 2015 Y.Sugahara (moveccr)
3  * Copyright (C) 2021 Tetsuya Isaki
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
21  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #pragma once
28 
29 #include "Diag.h"
30 #include "ImageReductor.h"
31 #include "StreamBase.h"
32 #include <vector>
33 
34 // SIXEL 出力モード。
35 // SIXEL のカラーモード値と同じにする。
36 enum SixelOutputMode {
37 	Normal = 1,	// 通常の SIXEL を出力する。
38 	Or = 5,		// OR モード SIXEL を出力する。
39 };
40 
41 // リサイズモード
42 enum SixelResizeMode
43 {
44 	// リサイズ処理をロード時にライブラリで行う。
45 	ByLoad,
46 
47 	// ロードは等倍で行い、その後にリサイズ処理を ImageReductor で行う。
48 	ByImageReductor,
49 };
50 
51 class SixelConverter
52 {
53  public:
54 	// コンストラクタ
55 	SixelConverter();
56 	SixelConverter(int debuglv);
57 
58 	// stream から読み込む
59 	bool LoadFromStream(InputStream *stream);
60 
61 	// インデックスカラーに変換する
62 	void ConvertToIndexed();
63 
64 	// Sixel を stream に出力する
65 	bool SixelToStream(OutputStream *stream);
66 
67 	// 画像の幅・高さを取得する
GetWidth()68 	int GetWidth() const { return Width; }
GetHeight()69 	int GetHeight() const { return Height; }
70 
71 	// ImageReductor を取得する
GetImageReductor()72 	ImageReductor& GetImageReductor() { return ir; }
73 
74 	// ----- 設定
75 
76 	// Sixel の出力カラーモード値
77 	SixelOutputMode OutputMode = SixelOutputMode::Normal;
78 
79 	// Sixel にパレットを出力するなら true
80 	bool OutputPalette = true;
81 
82 	// カラーモード
83 	ReductorColorMode ColorMode = ReductorColorMode::Fixed256;
84 
85 	// ファインダーモード
86 	ReductorFinderMode FinderMode = ReductorFinderMode::RFM_Default;
87 
88 	// グレーカラーの時の色数。グレー以外の時は無視される。
89 	int GrayCount = 256;
90 
91 	// 減色モード
92 	ReductorReduceMode ReduceMode = ReductorReduceMode::HighQuality;
93 
94 	// リサイズモード
95 	SixelResizeMode ResizeMode = SixelResizeMode::ByLoad;
96 
97 	// ノイズ付加
98 	// ベタ塗り画像で少ない色数に減色する時、ノイズを付加すると画質改善出来る
99 	int AddNoiseLevel {};
100 
101 	// リサイズ情報 (リサイズで希望する幅と高さ)。
102 	// 0 を指定するとその情報は使われない。
103 	int ResizeWidth {};
104 	int ResizeHeight {};
105 
106 	// リサイズ処理で使用する軸
107 	ResizeAxisMode ResizeAxis = ResizeAxisMode::Both;
108 
109  public:
110 	// インデックスカラー画像バッファ
111 	std::vector<uint8> Indexed {};
112 
113  private:
114 	void LoadAfter();
115 
116 	void CalcResize(int *width, int *height);
117 
118 	std::string SixelPreamble();
119 	bool SixelToStreamCore_ORmode(OutputStream *stream);
120 	bool SixelToStreamCore(OutputStream *stream);
121 	std::string SixelPostamble();
122 	static std::string SixelRepunit(int n, uint8 ptn);
123 
124 	ImageReductor ir {};
125 
126 	// 元画像
127 	Image img {};
128 
129 	// (出力する画像の)幅と高さ
130 	// リサイズしなければ img.Size.{w,h} と同じ
131 	int Width {};
132 	int Height {};
133 
134 	Diag diag {};
135 
136  public:
137 	// enum 対応
138 	static const char *SOM2str(SixelOutputMode val);
139 	static const char *SRM2str(SixelResizeMode val);
140 };
141 
142 // SixelConverterOR.cpp
143 extern int sixel_image_to_sixel_h6_ormode(uint8* dst, const uint8* src,
144 	int w, int h, int plane_count);
145