1 // This file is part of Deark.
2 // Copyright (C) 2016 Jason Summers
3 // See the file COPYING for terms of use.
7 // Data lookup and conversion.
9 #define DE_NOT_IN_MODULE
10 #include "deark-config.h"
12 #include "deark-private.h"
14 static const char *g_hexchars
= "0123456789abcdef";
16 char de_get_hexchar(int n
)
18 if(n
>=0 && n
<16) return g_hexchars
[n
];
22 static char de_get_hexcharUC(int n
)
24 static const char *hexcharsUC
= "0123456789ABCDEF";
25 if(n
>=0 && n
<16) return hexcharsUC
[n
];
29 u8
de_decode_hex_digit(u8 x
, int *errorflag
)
31 if(errorflag
) *errorflag
= 0;
32 if(x
>='0' && x
<='9') return x
-48;
33 if(x
>='A' && x
<='F') return x
-55;
34 if(x
>='a' && x
<='f') return x
-87;
35 if(errorflag
) *errorflag
= 1;
39 struct ext_ascii_pvt_data
{
40 const u16
*tbl
; // array[128]
43 static const u16 cp437table
[256] = {
44 0x00a0,0x263a,0x263b,0x2665,0x2666,0x2663,0x2660,0x2022,0x25d8,0x25cb,0x25d9,0x2642,0x2640,0x266a,0x266b,0x263c,
45 0x25ba,0x25c4,0x2195,0x203c,0x00b6,0x00a7,0x25ac,0x21a8,0x2191,0x2193,0x2192,0x2190,0x221f,0x2194,0x25b2,0x25bc,
46 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f,
47 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f,
48 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f,
49 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f,
50 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f,
51 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x2302,
52 0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7,0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x00ec,0x00c4,0x00c5,
53 0x00c9,0x00e6,0x00c6,0x00f4,0x00f6,0x00f2,0x00fb,0x00f9,0x00ff,0x00d6,0x00dc,0x00a2,0x00a3,0x00a5,0x20a7,0x0192,
54 0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba,0x00bf,0x2310,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb,
55 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510,
56 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567,
57 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580,
58 0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4,0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229,
59 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0
62 static const u16 latin2table
[32] = { // 0xa0 to 0xbf
63 0x00a0,0x0104,0x02d8,0x0141,0x00a4,0x013d,0x015a,0x00a7,0x00a8,0x0160,0x015e,0x0164,0x0179,0x00ad,0x017d,0x017b,
64 0x00b0,0x0105,0x02db,0x0142,0x00b4,0x013e,0x015b,0x02c7,0x00b8,0x0161,0x015f,0x0165,0x017a,0x02dd,0x017e,0x017c
67 static const u16 windows1250table
[128] = {
68 0x20ac,0xffff,0x201a,0xffff,0x201e,0x2026,0x2020,0x2021,0xffff,0x2030,0x0160,0x2039,0x015a,0x0164,0x017d,0x0179,
69 0xffff,0x2018,0x2019,0x201c,0x201d,0x2022,0x2013,0x2014,0xffff,0x2122,0x0161,0x203a,0x015b,0x0165,0x017e,0x017a,
70 0x00a0,0x02c7,0x02d8,0x0141,0x00a4,0x0104,0x00a6,0x00a7,0x00a8,0x00a9,0x015e,0x00ab,0x00ac,0x00ad,0x00ae,0x017b,
71 0x00b0,0x00b1,0x02db,0x0142,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x0105,0x015f,0x00bb,0x013d,0x02dd,0x013e,0x017c,
72 0x0154,0x00c1,0x00c2,0x0102,0x00c4,0x0139,0x0106,0x00c7,0x010c,0x00c9,0x0118,0x00cb,0x011a,0x00cd,0x00ce,0x010e,
73 0x0110,0x0143,0x0147,0x00d3,0x00d4,0x0150,0x00d6,0x00d7,0x0158,0x016e,0x00da,0x0170,0x00dc,0x00dd,0x0162,0x00df,
74 0x0155,0x00e1,0x00e2,0x0103,0x00e4,0x013a,0x0107,0x00e7,0x010d,0x00e9,0x0119,0x00eb,0x011b,0x00ed,0x00ee,0x010f,
75 0x0111,0x0144,0x0148,0x00f3,0x00f4,0x0151,0x00f6,0x00f7,0x0159,0x016f,0x00fa,0x0171,0x00fc,0x00fd,0x0163,0x02d9
77 static const struct ext_ascii_pvt_data windows1250_pvt_data
= { windows1250table
};
79 static const u16 windows1251table
[128] = {
80 0x0402,0x0403,0x201a,0x0453,0x201e,0x2026,0x2020,0x2021,0x20ac,0x2030,0x0409,0x2039,0x040a,0x040c,0x040b,0x040f,
81 0x0452,0x2018,0x2019,0x201c,0x201d,0x2022,0x2013,0x2014,0xffff,0x2122,0x0459,0x203a,0x045a,0x045c,0x045b,0x045f,
82 0x00a0,0x040e,0x045e,0x0408,0x00a4,0x0490,0x00a6,0x00a7,0x0401,0x00a9,0x0404,0x00ab,0x00ac,0x00ad,0x00ae,0x0407,
83 0x00b0,0x00b1,0x0406,0x0456,0x0491,0x00b5,0x00b6,0x00b7,0x0451,0x2116,0x0454,0x00bb,0x0458,0x0405,0x0455,0x0457,
84 0x0410,0x0411,0x0412,0x0413,0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f,
85 0x0420,0x0421,0x0422,0x0423,0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f,
86 0x0430,0x0431,0x0432,0x0433,0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f,
87 0x0440,0x0441,0x0442,0x0443,0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f
89 static const struct ext_ascii_pvt_data windows1251_pvt_data
= { windows1251table
};
91 static const u16 windows1252table
[32] = {
92 0x20ac,0xffff,0x201a,0x0192,0x201e,0x2026,0x2020,0x2021,0x02c6,0x2030,0x0160,0x2039,0x0152,0xffff,0x017d,0xffff,
93 0xffff,0x2018,0x2019,0x201c,0x201d,0x2022,0x2013,0x2014,0x02dc,0x2122,0x0161,0x203a,0x0153,0xffff,0x017e,0x0178
96 static const u16 windows1253table
[128] = {
97 0x20ac,0xffff,0x201a,0x0192,0x201e,0x2026,0x2020,0x2021,0xffff,0x2030,0xffff,0x2039,0xffff,0xffff,0xffff,0xffff,
98 0xffff,0x2018,0x2019,0x201c,0x201d,0x2022,0x2013,0x2014,0xffff,0x2122,0xffff,0x203a,0xffff,0xffff,0xffff,0xffff,
99 0x00a0,0x0385,0x0386,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0xffff,0x00ab,0x00ac,0x00ad,0x00ae,0x2015,
100 0x00b0,0x00b1,0x00b2,0x00b3,0x0384,0x00b5,0x00b6,0x00b7,0x0388,0x0389,0x038a,0x00bb,0x038c,0x00bd,0x038e,0x038f,
101 0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398,0x0399,0x039a,0x039b,0x039c,0x039d,0x039e,0x039f,
102 0x03a0,0x03a1,0xffff,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,0x03a8,0x03a9,0x03aa,0x03ab,0x03ac,0x03ad,0x03ae,0x03af,
103 0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,0x03b8,0x03b9,0x03ba,0x03bb,0x03bc,0x03bd,0x03be,0x03bf,
104 0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,0x03c8,0x03c9,0x03ca,0x03cb,0x03cc,0x03cd,0x03ce,0xffff
106 static const struct ext_ascii_pvt_data windows1253_pvt_data
= { windows1253table
};
108 static const u16 windows1254table
[128] = {
109 0x20ac,0xffff,0x201a,0x0192,0x201e,0x2026,0x2020,0x2021,0x02c6,0x2030,0x0160,0x2039,0x0152,0xffff,0xffff,0xffff,
110 0xffff,0x2018,0x2019,0x201c,0x201d,0x2022,0x2013,0x2014,0x02dc,0x2122,0x0161,0x203a,0x0153,0xffff,0xffff,0x0178,
111 0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,
112 0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,
113 0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,
114 0x011e,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x0130,0x015e,0x00df,
115 0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,
116 0x011f,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x0131,0x015f,0x00ff
118 static const struct ext_ascii_pvt_data windows1254_pvt_data
= { windows1254table
};
120 static const i32 atarist_table_lo
[32] = { // [0..31]
121 0x0000, 0x21e7, 0x21e9, 0x21e8, 0x21e6,0x1fbbd,0x1fbbe,0x1fbbf,
122 0x2713,0x1f552,0x1f514, 0x266a, 0x240c, 0x240d, 0xffff, 0xffff,
123 0x1fbf0,0x1fbf1,0x1fbf2,0x1fbf3,0x1fbf4,0x1fbf5,0x1fbf6,0x1fbf7,
124 0x1fbf8,0x1fbf9, 0x0259, 0x241b, 0xffff, 0xffff, 0xffff, 0xffff
127 static const u16 atarist_table_hi
[80] = { // [176..255]
128 0x00e3,0x00f5,0x00d8,0x00f8,0x0153,0x0152,0x00c0,0x00c3,0x00d5,0x00a8,0x00b4,0x2020,0x00b6,0x00a9,0x00ae,0x2122,
129 0x0133,0x0132,0x05d0,0x05d1,0x05d2,0x05d3,0x05d4,0x05d5,0x05d6,0x05d7,0x05d8,0x05d9,0x05db,0x05dc,0x05de,0x05e0,
130 0x05e1,0x05e2,0x05e4,0x05e6,0x05e7,0x05e8,0x05e9,0x05ea,0x05df,0x05da,0x05dd,0x05e3,0x05e5,0x00a7,0x2227,0x221e,
131 0x03b1,0x03b2,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4,0x03a6,0x0398,0x03a9,0x03b4,0x222e,0x03d5,0x2208,0x2229,
132 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,0x00b0,0x2022,0x00b7,0x221a,0x207f,0x00b2,0x00b3,0x00af
135 // Trivia: This table maps the heart and diamond suits to the BLACK Unicode
136 // characters. Some sources map them to the WHITE characters instead.
137 static const u16 palmcstable
[4] = {
138 0x2666,0x2663,0x2665,0x2660
141 static const u16 riscostable
[32] = {
142 0x20ac,0x0174,0x0175,0xffff,0xffff,0x0176,0x0177,0xffff,0xffff,0xffff,0xffff,0xffff,0x2026,0x2122,0x2030,0x2022,
143 0x2018,0x2019,0x2039,0x203a,0x201c,0x201d,0x201e,0x2013,0x2014,0x2212,0x0152,0x0153,0x2020,0x2021,0xfb01,0xfb02
146 // MacRoman, a.k.a "Mac OS Roman", "Macintosh"
147 static const u16 macromantable
[128] = {
148 0x00c4,0x00c5,0x00c7,0x00c9,0x00d1,0x00d6,0x00dc,0x00e1,0x00e0,0x00e2,0x00e4,0x00e3,0x00e5,0x00e7,0x00e9,0x00e8,
149 0x00ea,0x00eb,0x00ed,0x00ec,0x00ee,0x00ef,0x00f1,0x00f3,0x00f2,0x00f4,0x00f6,0x00f5,0x00fa,0x00f9,0x00fb,0x00fc,
150 0x2020,0x00b0,0x00a2,0x00a3,0x00a7,0x2022,0x00b6,0x00df,0x00ae,0x00a9,0x2122,0x00b4,0x00a8,0x2260,0x00c6,0x00d8,
151 0x221e,0x00b1,0x2264,0x2265,0x00a5,0x00b5,0x2202,0x2211,0x220f,0x03c0,0x222b,0x00aa,0x00ba,0x03a9,0x00e6,0x00f8,
152 0x00bf,0x00a1,0x00ac,0x221a,0x0192,0x2248,0x2206,0x00ab,0x00bb,0x2026,0x00a0,0x00c0,0x00c3,0x00d5,0x0152,0x0153,
153 0x2013,0x2014,0x201c,0x201d,0x2018,0x2019,0x00f7,0x25ca,0x00ff,0x0178,0x2044,0x20ac,0x2039,0x203a,0xfb01,0xfb02,
154 0x2021,0x00b7,0x201a,0x201e,0x2030,0x00c2,0x00ca,0x00c1,0x00cb,0x00c8,0x00cd,0x00ce,0x00cf,0x00cc,0x00d3,0x00d4,
155 0xf8ff,0x00d2,0x00da,0x00db,0x00d9,0x0131,0x02c6,0x02dc,0x00af,0x02d8,0x02d9,0x02da,0x00b8,0x02dd,0x02db,0x02c7
157 static const struct ext_ascii_pvt_data macroman_pvt_data
= { macromantable
};
159 // Note: This is not an official or canonical mapping.
160 static const i32 petscii1table
[256] = {
161 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x000d,0x000e,0xffff,
162 0xffff,0xffff,0xffff,0xffff,0x007f,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
163 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f,
164 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f,
165 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f,
166 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x00a3,0x005d,0x2191,0x2190,
167 0x2500,0x2660,0x2502,0x2500,0x1fb77,0x1fb76,0x1fb7a,0x1fb71,0x1fb74,0x256e,0x2570,0x256f,0x1fb7c,0x2572,0x2571,0x1fb7d,
168 0x1fb7e,0x25cf,0x1fb7b,0x2665,0x1fb70,0x256d,0x2573,0x25cb,0x2663,0x1fb75,0x2666,0x253c,0x1fb8c,0x2502,0x03c0,0x25e5,
169 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x000a,0x000f,0xffff,
170 0xffff,0xffff,0xffff,0x000c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x0008,0xffff,0xffff,
171 0x00a0,0x258c,0x2584,0x2594,0x2581,0x258e,0x2592,0x2595,0x1fb8f,0x25e4,0x1fb87,0x251c,0x2597,0x2514,0x2510,0x2582,
172 0x250c,0x2534,0x252c,0x2524,0x258e,0x258d,0x1fb88,0x1fb82,0x1fb83,0x2583,0x1fb7f,0x2596,0x259d,0x2518,0x2598,0x259a,
173 0x2500,0x2660,0x2502,0x2500,0x1fb77,0x1fb76,0x1fb7a,0x1fb71,0x1fb74,0x256e,0x2570,0x256f,0x1fb7c,0x2572,0x2571,0x1fb7d,
174 0x1fb7e,0x25cf,0x1fb7b,0x2665,0x1fb70,0x256d,0x2573,0x25cb,0x2663,0x1fb75,0x2666,0x253c,0x1fb8c,0x2502,0x03c0,0x25e5,
175 0x00a0,0x258c,0x2584,0x2594,0x2581,0x258e,0x2592,0x2595,0x1fb8f,0x25e4,0x1fb87,0x251c,0x2597,0x2514,0x2510,0x2582,
176 0x250c,0x2534,0x252c,0x2524,0x258e,0x258d,0x1fb88,0x1fb82,0x1fb83,0x2583,0x1fb7f,0x2596,0x259d,0x2518,0x2598,0x03c0
179 // Derived from VT100 Series Technical manual, Table A-9: Special Graphics Characters (p. A-12)
180 static const u16 decspecialgraphicstable
[32] = {
181 0x00a0,0x25c6,0x2592,0x2409,0x240c,0x240d,0x240a,0x00b0,0x00b1,0x2424,0x240b,0x2518,0x2510,0x250c,0x2514,0x253c,
182 0x23ba,0x23bb,0x2500,0x23bc,0x23bd,0x251c,0x2524,0x2534,0x252c,0x2502,0x2264,0x2265,0x03c0,0x2260,0x00a3,0x00b7
185 // Code page 437, with screen code graphics characters.
186 static de_rune
de_cp437g_to_unicode(struct de_encconv_state
*es
, i32 a
)
189 if(a
<=0xff) n
= (de_rune
)cp437table
[a
];
190 else n
= DE_CODEPOINT_INVALID
;
191 if(n
==0xffff) n
= DE_CODEPOINT_INVALID
;
195 // Code page 437, with control characters.
196 static de_rune
de_cp437c_to_unicode(struct de_encconv_state
*es
, i32 a
)
200 else if(a
>=0x80 && a
<=0xff) n
= (de_rune
)cp437table
[a
];
201 else n
= DE_CODEPOINT_INVALID
;
202 if(n
==0xffff) n
= DE_CODEPOINT_INVALID
;
206 // Code page 437, with only selected control characters.
207 static de_rune
de_cp437h_to_unicode(struct de_encconv_state
*es
, i32 a
)
211 if(a
==0 || a
==9 || a
==10 || a
==13) n
= a
;
212 else n
= de_cp437g_to_unicode(NULL
, a
);
216 static de_rune
de_latin2_to_unicode(struct de_encconv_state
*es
, i32 a
)
220 else if(a
>=0xa0 && a
<=0xbf) n
= (de_rune
)latin2table
[a
-0xa0];
221 else if(a
>=0x0c0 && a
<=0xff) n
= (de_rune
)windows1250table
[a
-0x80];
222 else n
= DE_CODEPOINT_INVALID
;
223 if(n
==0xffff) n
= DE_CODEPOINT_INVALID
;
227 static de_rune
de_windows1252_to_unicode(struct de_encconv_state
*es
, i32 a
)
230 if(a
>=0x80 && a
<=0x9f) n
= (de_rune
)windows1252table
[a
-0x80];
231 else if(a
<=0xff) n
= a
;
232 else n
= DE_CODEPOINT_INVALID
;
233 if(n
==0xffff) n
= DE_CODEPOINT_INVALID
;
237 static de_rune
de_windows874_to_unicode(struct de_encconv_state
*es
, i32 a
)
240 if(a
<=0x7f || a
==0xa0) n
= a
;
241 else if(a
==0x80 || a
==0x85 || (a
>=0x91 && a
<=0x97)) n
= (de_rune
)windows1252table
[a
-0x80];
242 else if((a
>=0xa1 && a
<=0xda) || (a
>=0xdf && a
<=0xfb)) n
= a
+ (0xe01 - 0xa1);
243 if(n
==0xffff) n
= DE_CODEPOINT_INVALID
;
247 static de_rune
de_atarist_to_unicode(struct de_encconv_state
*es
, i32 a
)
251 if(a
<=0x1f || a
==0x7f) {
252 int st
= DE_EXTENC_GET_SUBTYPE(es
->ee
);
254 if (st
==DE_ENCSUBTYPE_HYBRID
|| st
==DE_ENCSUBTYPE_CONTROLS
) {
258 if(a
<=0x1f) n
= atarist_table_lo
[a
];
259 else if(a
>=0xb0 && a
<=0xff) n
= (de_rune
)atarist_table_hi
[a
-0xb0];
260 else if(a
==0x7f) n
= 0x0394;
261 else if(a
==0x9e) n
= 0x00df;
262 else n
= de_cp437g_to_unicode(NULL
, a
);
263 if(n
==0xffff) n
= DE_CODEPOINT_INVALID
;
267 static de_rune
de_palmcs_to_unicode(struct de_encconv_state
*es
, i32 a
)
270 // This is not perfect, but the diamond/club/heart/spade characters seem to
271 // be about the only printable characters common to all versions of this
272 // encoding, that differ from Windows-1252.
273 if(a
>=0x8d && a
<=0x90) n
= (de_rune
)palmcstable
[a
-0x8d];
274 else n
= de_windows1252_to_unicode(NULL
, a
);
278 static de_rune
de_riscos_to_unicode(struct de_encconv_state
*es
, i32 a
)
281 if(a
>=0x80 && a
<=0x9f) n
= (de_rune
)riscostable
[a
-0x80];
282 else if(a
<=0xff) n
= a
;
283 else n
= DE_CODEPOINT_INVALID
;
284 if(n
==0xffff) n
= DE_CODEPOINT_INVALID
;
288 static de_rune
de_petscii_to_unicode(struct de_encconv_state
*es
, i32 a
)
291 if(a
<=0xff) n
= petscii1table
[a
];
292 else n
= DE_CODEPOINT_INVALID
;
293 if(n
==0xffff) n
= DE_CODEPOINT_INVALID
;
295 // This is a hack to make "-m plaintext -inenc petscii" work with the
296 // output from the basic_c64 module.
297 if(DE_EXTENC_GET_SUBTYPE(es
->ee
)==DE_ENCSUBTYPE_HYBRID
) {
304 static de_rune
de_appleii_to_unicode(struct de_encconv_state
*es
, i32 a
)
308 // This suffices to support some text files I've seen, but I really don't know
309 // what all is needed for Apple II text.
310 n
= (de_rune
)(a
& 0x7f);
311 if(n
==0x0d) n
= 0x0a;
315 static de_rune
de_decspecialgraphics_to_unicode(struct de_encconv_state
*es
, i32 a
)
318 if(a
>=95 && a
<=126) n
= (de_rune
)decspecialgraphicstable
[a
-95];
319 else n
= DE_CODEPOINT_INVALID
;
320 if(n
==0xffff) n
= DE_CODEPOINT_INVALID
;
325 // Intended for testing, as an easy way to check that encoding translation is
326 // working, even when the source data is plain ASCII.
327 static de_rune
de_rot13_to_unicode(struct de_encconv_state
*es
, i32 a
)
331 if((a
>='A' && a
<='M') || (a
>='a' && a
<='m')) {
334 else if((a
>='N' && a
<='Z') || (a
>='n' && a
<='z')) {
344 // For any charset that uses 128 ASCII chars + 128 custom chars.
345 static de_rune
de_ext_ascii_to_unicode(struct de_encconv_state
*es
, i32 a
)
350 else if(a
>=0x80 && a
<=0xff) n
= (de_rune
)((struct ext_ascii_pvt_data
*)es
->fn_pvt_data
)->tbl
[a
-0x80];
351 else n
= DE_CODEPOINT_INVALID
;
352 if(n
==0xffff) n
= DE_CODEPOINT_INVALID
;
356 void de_encconv_init(struct de_encconv_state
*es
, de_ext_encoding ee
)
358 de_encoding enc
= DE_EXTENC_GET_BASE(ee
);
360 de_zeromem(es
, sizeof(struct de_encconv_state
));
363 if(enc
==DE_ENCODING_LATIN1
|| enc
==DE_ENCODING_UTF8
||
364 enc
==DE_ENCODING_ASCII
)
370 case DE_ENCODING_LATIN2
:
371 es
->fn
= de_latin2_to_unicode
;
373 case DE_ENCODING_CP437
:
374 switch(DE_EXTENC_GET_SUBTYPE(es
->ee
)) {
375 case DE_ENCSUBTYPE_CONTROLS
:
376 es
->fn
= de_cp437c_to_unicode
;
378 case DE_ENCSUBTYPE_HYBRID
:
379 es
->fn
= de_cp437h_to_unicode
;
382 es
->fn
= de_cp437g_to_unicode
;
385 case DE_ENCODING_PETSCII
:
386 es
->fn
= de_petscii_to_unicode
;
388 case DE_ENCODING_WINDOWS1252
:
389 es
->fn
= de_windows1252_to_unicode
;
391 case DE_ENCODING_MACROMAN
:
392 es
->fn
= de_ext_ascii_to_unicode
;
393 es
->fn_pvt_data
= (const void*)¯oman_pvt_data
;
395 case DE_ENCODING_WINDOWS1250
:
396 es
->fn
= de_ext_ascii_to_unicode
;
397 es
->fn_pvt_data
= (const void*)&windows1250_pvt_data
;
399 case DE_ENCODING_WINDOWS1251
:
400 es
->fn
= de_ext_ascii_to_unicode
;
401 es
->fn_pvt_data
= (const void*)&windows1251_pvt_data
;
403 case DE_ENCODING_WINDOWS1253
:
404 es
->fn
= de_ext_ascii_to_unicode
;
405 es
->fn_pvt_data
= (const void*)&windows1253_pvt_data
;
407 case DE_ENCODING_WINDOWS1254
:
408 es
->fn
= de_ext_ascii_to_unicode
;
409 es
->fn_pvt_data
= (const void*)&windows1254_pvt_data
;
411 case DE_ENCODING_WINDOWS874
:
412 es
->fn
= de_windows874_to_unicode
;
414 case DE_ENCODING_ATARIST
:
415 es
->fn
= de_atarist_to_unicode
;
417 case DE_ENCODING_PALM
:
418 es
->fn
= de_palmcs_to_unicode
;
420 case DE_ENCODING_RISCOS
:
421 es
->fn
= de_riscos_to_unicode
;
423 case DE_ENCODING_APPLEII
:
424 es
->fn
= de_appleii_to_unicode
;
426 case DE_ENCODING_DEC_SPECIAL_GRAPHICS
:
427 es
->fn
= de_decspecialgraphics_to_unicode
;
429 case DE_ENCODING_ROT13
:
430 es
->fn
= de_rot13_to_unicode
;
437 de_rune
de_char_to_unicode_ex(i32 a
, struct de_encconv_state
*es
)
439 if(a
<0) return DE_CODEPOINT_INVALID
;
441 return es
->fn(es
, a
);
444 switch(DE_EXTENC_GET_BASE(es
->ee
)) {
445 case DE_ENCODING_ASCII
:
446 if(DE_EXTENC_GET_SUBTYPE(es
->ee
)==DE_ENCSUBTYPE_PRINTABLE
) {
447 return (a
>=32 && a
<=126)?a
:DE_CODEPOINT_INVALID
;
449 return (a
<128)?a
:DE_CODEPOINT_INVALID
;
450 case DE_ENCODING_LATIN1
:
451 return (a
<256)?a
:DE_CODEPOINT_INVALID
;
458 de_rune
de_char_to_unicode(deark
*c
, i32 a
, de_ext_encoding ee
)
460 struct de_encconv_state es
;
462 de_encconv_init(&es
, ee
);
463 return de_char_to_unicode_ex(a
, &es
);
466 // Encode a Unicode char in UTF-8.
467 // Caller supplies utf8buf[4].
468 // Sets *p_utf8len to the number of bytes used (1-4).
469 void de_uchar_to_utf8(de_rune u1
, u8
*utf8buf
, i64
*p_utf8len
)
473 // TODO: Maybe there should be a flag to tell what to do with
474 // our special codepoints (DE_CODEPOINT_BYTE00, ...).
475 if(u1
<0 || u1
>0x10ffff) {
483 else if(u
>=0x80 && u
<=0x7ff) {
485 utf8buf
[0] = 0xc0 | (u8
)(u
>>6);
486 utf8buf
[1] = 0x80 | (u
&0x3f);
488 else if(u
>=0x800 && u
<=0xffff) {
490 utf8buf
[0] = 0xe0 | (u8
)(u
>>12);
491 utf8buf
[1] = 0x80 | ((u
>>6)&0x3f);
492 utf8buf
[2] = 0x80 | (u
&0x3f);
496 utf8buf
[0] = 0xf0 | (u8
)(u
>>18);
497 utf8buf
[1] = 0x80 | ((u
>>12)&0x3f);
498 utf8buf
[2] = 0x80 | ((u
>>6)&0x3f);
499 utf8buf
[3] = 0x80 | (u
&0x3f);
503 // Write a unicode code point to a file, encoded as UTF-8.
504 void dbuf_write_uchar_as_utf8(dbuf
*outf
, de_rune u
)
509 de_uchar_to_utf8(u
, utf8buf
, &utf8len
);
510 dbuf_write(outf
, utf8buf
, utf8len
);
513 // Convert a UTF-8 character to UTF-32.
514 // Returns 1 if a valid character was converted, 0 otherwise.
515 // buflen = the max number of bytes to read (but regardless of buflen, this
516 // will not read past a byte whose value is < 0x80).
518 // TODO?: There is another UTF-8 decoder in ucstring_append_bytes_ex(). Maybe
519 // should be consolidated in some way.
520 int de_utf8_to_uchar(const u8
*utf8buf
, i64 buflen
,
521 de_rune
*p_uchar
, i64
*p_utf8len
)
528 if(buflen
<1) return 0;
529 u0
= (i32
)utf8buf
[0];
530 if(u0
<=0x7f) { // 1-byte UTF-8 char
535 if(buflen
<2) return 0;
536 if((utf8buf
[1]&0xc0)!=0x80) return 0;
537 u1
= (i32
)utf8buf
[1];
538 if(u0
<=0xdf) { // 2-byte UTF-8 char
540 *p_uchar
= ((u0
&0x1f)<<6) | (u1
&0x3f);
543 if(buflen
<3) return 0;
544 if((utf8buf
[2]&0xc0)!=0x80) return 0;
545 u2
= (i32
)utf8buf
[2];
546 if(u0
<=0xef) { // 3-byte UTF-8 char
548 *p_uchar
= ((u0
&0x0f)<<12) | ((u1
&0x3f)<<6) | (u2
&0x3f);
551 if(buflen
<4) return 0;
552 if((utf8buf
[3]&0xc0)!=0x80) return 0;
553 u3
= (i32
)utf8buf
[3];
554 if(u0
<=0xf7) { // 4-byte UTF-8 char
556 *p_uchar
= ((u0
&0x07)<<18) | ((u1
&0x3f)<<12) | ((u2
&0x3f)<<6) | (u3
&0x3f);
562 // Copy a string, converting from UTF-8 to ASCII.
563 // Non-ASCII characters will be replaced, one way or another.
564 void de_utf8_to_ascii(const char *src
, char *dst
, size_t dstlen
, unsigned int flags
)
574 char sc
; // substitution character 1
575 char sc2
= 0; // substitution character 2
577 if(dstpos
>= dstlen
-1) {
578 dst
[dstlen
-1] = '\0';
582 ch
= (unsigned char)src
[srcpos
];
584 dst
[dstpos
++] = src
[srcpos
++];
588 else { // Start of a multi-byte UTF8 char
590 ret
= de_utf8_to_uchar((const u8
*)&src
[srcpos
], 4, &uchar
, &code_len
);
592 srcpos
+= (size_t)code_len
;
594 case 0x00d7: sc
='x'; break; // Multiplication sign
595 case 0x2018: case 0x2019: sc
='\''; break; // single quotes
596 case 0x201c: case 0x201d: sc
='"'; break; // double quotes
597 case 0x2192: sc
='-'; sc2
='>'; break; // Rightwards arrow
598 case 0x2264: sc
='<'; sc2
='='; break;
599 case 0x2265: sc
='>'; sc2
='='; break;
600 case 0x2502: sc
='|'; break; // Box drawings light vertical
609 if(sc2
&& dstpos
<dstlen
-1) dst
[dstpos
++] = sc2
;
614 // Given a buffer, return 1 if it has no bytes 0x80 or higher.
615 int de_is_ascii(const u8
*buf
, i64 buflen
)
619 for(i
=0; i
<buflen
; i
++) {
620 if(buf
[i
]>=128) return 0;
625 static const u8 stdpal_vga256_colors
[256*3] = {
626 0x00,0x00,0x00,0x00,0x00,0xaa,0x00,0xaa,0x00,0x00,0xaa,0xaa,0xaa,0x00,0x00,0xaa,0x00,0xaa,
627 0xaa,0x55,0x00,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,0x55,0xff,0x55,0xff,0x55,0x55,0xff,0xff,
628 0xff,0x55,0x55,0xff,0x55,0xff,0xff,0xff,0x55,0xff,0xff,0xff,0x00,0x00,0x00,0x14,0x14,0x14,
629 0x20,0x20,0x20,0x2d,0x2d,0x2d,0x39,0x39,0x39,0x45,0x45,0x45,0x51,0x51,0x51,0x61,0x61,0x61,
630 0x71,0x71,0x71,0x82,0x82,0x82,0x92,0x92,0x92,0xa2,0xa2,0xa2,0xb6,0xb6,0xb6,0xca,0xca,0xca,
631 0xe3,0xe3,0xe3,0xff,0xff,0xff,0x00,0x00,0xff,0x41,0x00,0xff,0x7d,0x00,0xff,0xbe,0x00,0xff,
632 0xff,0x00,0xff,0xff,0x00,0xbe,0xff,0x00,0x7d,0xff,0x00,0x41,0xff,0x00,0x00,0xff,0x41,0x00,
633 0xff,0x7d,0x00,0xff,0xbe,0x00,0xff,0xff,0x00,0xbe,0xff,0x00,0x7d,0xff,0x00,0x41,0xff,0x00,
634 0x00,0xff,0x00,0x00,0xff,0x41,0x00,0xff,0x7d,0x00,0xff,0xbe,0x00,0xff,0xff,0x00,0xbe,0xff,
635 0x00,0x7d,0xff,0x00,0x41,0xff,0x7d,0x7d,0xff,0x9e,0x7d,0xff,0xbe,0x7d,0xff,0xdf,0x7d,0xff,
636 0xff,0x7d,0xff,0xff,0x7d,0xdf,0xff,0x7d,0xbe,0xff,0x7d,0x9e,0xff,0x7d,0x7d,0xff,0x9e,0x7d,
637 0xff,0xbe,0x7d,0xff,0xdf,0x7d,0xff,0xff,0x7d,0xdf,0xff,0x7d,0xbe,0xff,0x7d,0x9e,0xff,0x7d,
638 0x7d,0xff,0x7d,0x7d,0xff,0x9e,0x7d,0xff,0xbe,0x7d,0xff,0xdf,0x7d,0xff,0xff,0x7d,0xdf,0xff,
639 0x7d,0xbe,0xff,0x7d,0x9e,0xff,0xb6,0xb6,0xff,0xc6,0xb6,0xff,0xdb,0xb6,0xff,0xeb,0xb6,0xff,
640 0xff,0xb6,0xff,0xff,0xb6,0xeb,0xff,0xb6,0xdb,0xff,0xb6,0xc6,0xff,0xb6,0xb6,0xff,0xc6,0xb6,
641 0xff,0xdb,0xb6,0xff,0xeb,0xb6,0xff,0xff,0xb6,0xeb,0xff,0xb6,0xdb,0xff,0xb6,0xc6,0xff,0xb6,
642 0xb6,0xff,0xb6,0xb6,0xff,0xc6,0xb6,0xff,0xdb,0xb6,0xff,0xeb,0xb6,0xff,0xff,0xb6,0xeb,0xff,
643 0xb6,0xdb,0xff,0xb6,0xc6,0xff,0x00,0x00,0x71,0x1c,0x00,0x71,0x39,0x00,0x71,0x55,0x00,0x71,
644 0x71,0x00,0x71,0x71,0x00,0x55,0x71,0x00,0x39,0x71,0x00,0x1c,0x71,0x00,0x00,0x71,0x1c,0x00,
645 0x71,0x39,0x00,0x71,0x55,0x00,0x71,0x71,0x00,0x55,0x71,0x00,0x39,0x71,0x00,0x1c,0x71,0x00,
646 0x00,0x71,0x00,0x00,0x71,0x1c,0x00,0x71,0x39,0x00,0x71,0x55,0x00,0x71,0x71,0x00,0x55,0x71,
647 0x00,0x39,0x71,0x00,0x1c,0x71,0x39,0x39,0x71,0x45,0x39,0x71,0x55,0x39,0x71,0x61,0x39,0x71,
648 0x71,0x39,0x71,0x71,0x39,0x61,0x71,0x39,0x55,0x71,0x39,0x45,0x71,0x39,0x39,0x71,0x45,0x39,
649 0x71,0x55,0x39,0x71,0x61,0x39,0x71,0x71,0x39,0x61,0x71,0x39,0x55,0x71,0x39,0x45,0x71,0x39,
650 0x39,0x71,0x39,0x39,0x71,0x45,0x39,0x71,0x55,0x39,0x71,0x61,0x39,0x71,0x71,0x39,0x61,0x71,
651 0x39,0x55,0x71,0x39,0x45,0x71,0x51,0x51,0x71,0x59,0x51,0x71,0x61,0x51,0x71,0x69,0x51,0x71,
652 0x71,0x51,0x71,0x71,0x51,0x69,0x71,0x51,0x61,0x71,0x51,0x59,0x71,0x51,0x51,0x71,0x59,0x51,
653 0x71,0x61,0x51,0x71,0x69,0x51,0x71,0x71,0x51,0x69,0x71,0x51,0x61,0x71,0x51,0x59,0x71,0x51,
654 0x51,0x71,0x51,0x51,0x71,0x59,0x51,0x71,0x61,0x51,0x71,0x69,0x51,0x71,0x71,0x51,0x69,0x71,
655 0x51,0x61,0x71,0x51,0x59,0x71,0x00,0x00,0x41,0x10,0x00,0x41,0x20,0x00,0x41,0x31,0x00,0x41,
656 0x41,0x00,0x41,0x41,0x00,0x31,0x41,0x00,0x20,0x41,0x00,0x10,0x41,0x00,0x00,0x41,0x10,0x00,
657 0x41,0x20,0x00,0x41,0x31,0x00,0x41,0x41,0x00,0x31,0x41,0x00,0x20,0x41,0x00,0x10,0x41,0x00,
658 0x00,0x41,0x00,0x00,0x41,0x10,0x00,0x41,0x20,0x00,0x41,0x31,0x00,0x41,0x41,0x00,0x31,0x41,
659 0x00,0x20,0x41,0x00,0x10,0x41,0x20,0x20,0x41,0x28,0x20,0x41,0x31,0x20,0x41,0x39,0x20,0x41,
660 0x41,0x20,0x41,0x41,0x20,0x39,0x41,0x20,0x31,0x41,0x20,0x28,0x41,0x20,0x20,0x41,0x28,0x20,
661 0x41,0x31,0x20,0x41,0x39,0x20,0x41,0x41,0x20,0x39,0x41,0x20,0x31,0x41,0x20,0x28,0x41,0x20,
662 0x20,0x41,0x20,0x20,0x41,0x28,0x20,0x41,0x31,0x20,0x41,0x39,0x20,0x41,0x41,0x20,0x39,0x41,
663 0x20,0x31,0x41,0x20,0x28,0x41,0x2d,0x2d,0x41,0x31,0x2d,0x41,0x35,0x2d,0x41,0x3d,0x2d,0x41,
664 0x41,0x2d,0x41,0x41,0x2d,0x3d,0x41,0x2d,0x35,0x41,0x2d,0x31,0x41,0x2d,0x2d,0x41,0x31,0x2d,
665 0x41,0x35,0x2d,0x41,0x3d,0x2d,0x41,0x41,0x2d,0x3d,0x41,0x2d,0x35,0x41,0x2d,0x31,0x41,0x2d,
666 0x2d,0x41,0x2d,0x2d,0x41,0x31,0x2d,0x41,0x35,0x2d,0x41,0x3d,0x2d,0x41,0x41,0x2d,0x3d,0x41,
667 0x2d,0x35,0x41,0x2d,0x31,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
668 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
671 static const u8 stdpal_ega64_colors
[64*3] = {
672 0x00,0x00,0x00,0x00,0x00,0xaa,0x00,0xaa,0x00,0x00,0xaa,0xaa,0xaa,0x00,0x00,0xaa,0x00,0xaa,
673 0xaa,0xaa,0x00,0xaa,0xaa,0xaa,0x00,0x00,0x55,0x00,0x00,0xff,0x00,0xaa,0x55,0x00,0xaa,0xff,
674 0xaa,0x00,0x55,0xaa,0x00,0xff,0xaa,0xaa,0x55,0xaa,0xaa,0xff,0x00,0x55,0x00,0x00,0x55,0xaa,
675 0x00,0xff,0x00,0x00,0xff,0xaa,0xaa,0x55,0x00,0xaa,0x55,0xaa,0xaa,0xff,0x00,0xaa,0xff,0xaa,
676 0x00,0x55,0x55,0x00,0x55,0xff,0x00,0xff,0x55,0x00,0xff,0xff,0xaa,0x55,0x55,0xaa,0x55,0xff,
677 0xaa,0xff,0x55,0xaa,0xff,0xff,0x55,0x00,0x00,0x55,0x00,0xaa,0x55,0xaa,0x00,0x55,0xaa,0xaa,
678 0xff,0x00,0x00,0xff,0x00,0xaa,0xff,0xaa,0x00,0xff,0xaa,0xaa,0x55,0x00,0x55,0x55,0x00,0xff,
679 0x55,0xaa,0x55,0x55,0xaa,0xff,0xff,0x00,0x55,0xff,0x00,0xff,0xff,0xaa,0x55,0xff,0xaa,0xff,
680 0x55,0x55,0x00,0x55,0x55,0xaa,0x55,0xff,0x00,0x55,0xff,0xaa,0xff,0x55,0x00,0xff,0x55,0xaa,
681 0xff,0xff,0x00,0xff,0xff,0xaa,0x55,0x55,0x55,0x55,0x55,0xff,0x55,0xff,0x55,0x55,0xff,0xff,
682 0xff,0x55,0x55,0xff,0x55,0xff,0xff,0xff,0x55,0xff,0xff,0xff
685 static const u8 stdpal_pc16_colors
[16*3] = {
686 0x00,0x00,0x00,0x00,0x00,0xaa,0x00,0xaa,0x00,0x00,0xaa,0xaa,0xaa,0x00,0x00,0xaa,0x00,0xaa,
687 0xaa,0x55,0x00,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,0x55,0xff,0x55,0xff,0x55,0x55,0xff,0xff,
688 0xff,0x55,0x55,0xff,0x55,0xff,0xff,0xff,0x55,0xff,0xff,0xff
691 // This is a widely-used color set, but there seem to many different possible
692 // orders for the colors.
693 static const u8 stdpal_win16_colors_0
[16*3] = {
694 0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x80,
695 0x00,0x80,0x80,0x80,0x80,0x80,0xc0,0xc0,0xc0,0xff,0x00,0x00,0x00,0xff,0x00,0xff,0xff,0x00,
696 0x00,0x00,0xff,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0xff,0xff
699 static const u8 stdpal_win16_colors_1
[16*3] = {
700 0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x80,
701 0x00,0x80,0x80,0xc0,0xc0,0xc0,0x80,0x80,0x80,0xff,0x00,0x00,0x00,0xff,0x00,0xff,0xff,0x00,
702 0x00,0x00,0xff,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0xff,0xff
705 static const u8 stdpal_win16_colors_2
[16*3] = {
706 0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x80,0x00,0x80,
707 0x80,0x80,0x00,0x80,0x80,0x80,0xc0,0xc0,0xc0,0x00,0x00,0xff,0x00,0xff,0x00,0x00,0xff,0xff,
708 0xff,0x00,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff
711 static const u8 stdpals_cga
[6][4*3] = {
712 { 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0xaa, 0xaa, 0xaa, 0xaa }, // 0 = palette 1 low
713 { 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0x00, 0xaa, 0x55, 0x00 }, // 1 = palette 0 low
714 { 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xaa, 0xaa, 0xaa }, // 2 = 3rd palette low
715 { 0x00, 0x00, 0x00, 0x55, 0xff, 0xff, 0xff, 0x55, 0xff, 0xff, 0xff, 0xff }, // 3 = palette 1 high
716 { 0x00, 0x00, 0x00, 0x55, 0xff, 0x55, 0xff, 0x55, 0x55, 0xff, 0xff, 0x55 }, // 4 = palette 0 high
717 { 0x00, 0x00, 0x00, 0x55, 0xff, 0xff, 0xff, 0x55, 0x55, 0xff, 0xff, 0xff } // 5 = 3rd palette high
720 static const u8
*get_stdpal_colors(int pal_id
, int pal_subid
, i64
*pncolors
)
729 if(pal_subid
>=0 && pal_subid
<=5) {
730 p
= stdpals_cga
[pal_subid
];
738 p
= stdpal_pc16_colors
;
743 case 1: p
= stdpal_win16_colors_1
; break;
744 case 2: p
= stdpal_win16_colors_2
; break;
745 default: p
= stdpal_win16_colors_0
; break;
750 p
= stdpal_ega64_colors
;
752 case DE_PALID_VGA256
:
754 p
= stdpal_vga256_colors
;
760 // May be inefficient. de_copy_std_palette() is preferred.
761 de_color
de_get_std_palette_entry(int pal_id
, int pal_subid
, int index
)
766 pal
= get_stdpal_colors(pal_id
, pal_subid
, &stdpal_ncolors
);
767 if(!pal
|| index
<0 || index
>=(int)stdpal_ncolors
) {
768 return DE_STOCKCOLOR_BLACK
;
770 return DE_MAKE_RGB(pal
[index
*3], pal
[index
*3+1], pal
[index
*3+2]);
773 // starting_idx: The index of the color in the standard palette to be copied
775 // dstpal is indexed from 0...(dstpal_capacity-1).
777 // DE_COPYPALFLAG_INITPAL: Ensure all items in dstpal are set to something,
778 // even if the source palette is too short.
779 void de_copy_std_palette(int pal_id
, int pal_subid
, i64 starting_idx
,
780 de_color
*dstpal
, size_t dstpal_capacity
, UI flags
)
786 if(flags
& DE_COPYPALFLAG_INITPAL
) {
787 de_zeromem(dstpal
, dstpal_capacity
*sizeof(de_color
));
790 pal
= get_stdpal_colors(pal_id
, pal_subid
, &stdpal_ncolors
);
792 if(starting_idx
>= stdpal_ncolors
) goto done
;
794 n_to_copy
= de_min_int((i64
)dstpal_capacity
, stdpal_ncolors
- starting_idx
);
795 if(n_to_copy
<=0) goto done
;
796 de_copy_palette_from_rgb24(&pal
[starting_idx
*3], dstpal
, (size_t)n_to_copy
);
801 void de_copy_palette_from_rgb24(const u8
*src
, de_color
*dst
, size_t ncolors
)
805 for(i
=0; i
<ncolors
; i
++) {
806 dst
[i
] = DE_MAKE_RGB(src
[i
*3], src
[i
*3+1], src
[i
*3+2]);
810 // Only codepoints 32-127 are included here.
811 static const u8 cga_8x8_font_data
[96*8] = {
813 48,120,120,48,48,0,48,0,
814 108,108,108,0,0,0,0,0,
815 108,108,254,108,254,108,108,0,
816 48,124,192,120,12,248,48,0,
817 0,198,204,24,48,102,198,0,
818 56,108,56,118,220,204,118,0,
820 24,48,96,96,96,48,24,0,
821 96,48,24,24,24,48,96,0,
822 0,102,60,255,60,102,0,0,
823 0,48,48,252,48,48,0,0,
827 6,12,24,48,96,192,128,0,
828 124,198,206,222,246,230,124,0,
829 48,112,48,48,48,48,252,0,
830 120,204,12,56,96,204,252,0,
831 120,204,12,56,12,204,120,0,
832 28,60,108,204,254,12,30,0,
833 252,192,248,12,12,204,120,0,
834 56,96,192,248,204,204,120,0,
835 252,204,12,24,48,48,48,0,
836 120,204,204,120,204,204,120,0,
837 120,204,204,124,12,24,112,0,
839 0,48,48,0,0,48,48,96,
840 24,48,96,192,96,48,24,0,
842 96,48,24,12,24,48,96,0,
843 120,204,12,24,48,0,48,0,
844 124,198,222,222,222,192,120,0,
845 48,120,204,204,252,204,204,0,
846 252,102,102,124,102,102,252,0,
847 60,102,192,192,192,102,60,0,
848 248,108,102,102,102,108,248,0,
849 254,98,104,120,104,98,254,0,
850 254,98,104,120,104,96,240,0,
851 60,102,192,192,206,102,62,0,
852 204,204,204,252,204,204,204,0,
853 120,48,48,48,48,48,120,0,
854 30,12,12,12,204,204,120,0,
855 230,102,108,120,108,102,230,0,
856 240,96,96,96,98,102,254,0,
857 198,238,254,254,214,198,198,0,
858 198,230,246,222,206,198,198,0,
859 56,108,198,198,198,108,56,0,
860 252,102,102,124,96,96,240,0,
861 120,204,204,204,220,120,28,0,
862 252,102,102,124,108,102,230,0,
863 120,204,96,48,24,204,120,0,
864 252,180,48,48,48,48,120,0,
865 204,204,204,204,204,204,252,0,
866 204,204,204,204,204,120,48,0,
867 198,198,198,214,254,238,198,0,
868 198,198,108,56,56,108,198,0,
869 204,204,204,120,48,48,120,0,
870 254,198,140,24,50,102,254,0,
871 120,96,96,96,96,96,120,0,
872 192,96,48,24,12,6,2,0,
873 120,24,24,24,24,24,120,0,
874 16,56,108,198,0,0,0,0,
877 0,0,120,12,124,204,118,0,
878 224,96,96,124,102,102,220,0,
879 0,0,120,204,192,204,120,0,
880 28,12,12,124,204,204,118,0,
881 0,0,120,204,252,192,120,0,
882 56,108,96,240,96,96,240,0,
883 0,0,118,204,204,124,12,248,
884 224,96,108,118,102,102,230,0,
885 48,0,112,48,48,48,120,0,
886 12,0,12,12,12,204,204,120,
887 224,96,102,108,120,108,230,0,
888 112,48,48,48,48,48,120,0,
889 0,0,204,254,254,214,198,0,
890 0,0,248,204,204,204,204,0,
891 0,0,120,204,204,204,120,0,
892 0,0,220,102,102,124,96,240,
893 0,0,118,204,204,124,12,30,
894 0,0,220,118,102,96,240,0,
895 0,0,124,192,120,12,248,0,
896 16,48,124,48,48,52,24,0,
897 0,0,204,204,204,204,118,0,
898 0,0,204,204,204,120,48,0,
899 0,0,198,214,254,254,108,0,
900 0,0,198,108,56,108,198,0,
901 0,0,204,204,204,124,12,248,
902 0,0,252,152,48,100,252,0,
903 28,48,48,224,48,48,28,0,
904 24,24,24,0,24,24,24,0,
905 224,48,48,28,48,48,224,0,
907 0,16,56,108,198,198,254,0
910 const u8
*de_get_8x8ascii_font_ptr(void)
912 return cga_8x8_font_data
;
915 static const u8 vga_cp437_font_data
[256*16] = {
916 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
917 0,0,126,129,165,129,129,189,153,129,129,126,0,0,0,0,
918 0,0,126,255,219,255,255,195,231,255,255,126,0,0,0,0,
919 0,0,0,0,108,254,254,254,254,124,56,16,0,0,0,0,
920 0,0,0,0,16,56,124,254,124,56,16,0,0,0,0,0,
921 0,0,0,24,60,60,231,231,231,24,24,60,0,0,0,0,
922 0,0,0,24,60,126,255,255,126,24,24,60,0,0,0,0,
923 0,0,0,0,0,0,24,60,60,24,0,0,0,0,0,0,
924 255,255,255,255,255,255,231,195,195,231,255,255,255,255,255,255,
925 0,0,0,0,0,60,102,66,66,102,60,0,0,0,0,0,
926 255,255,255,255,255,195,153,189,189,153,195,255,255,255,255,255,
927 0,0,30,14,26,50,120,204,204,204,204,120,0,0,0,0,
928 0,0,60,102,102,102,102,60,24,126,24,24,0,0,0,0,
929 0,0,63,51,63,48,48,48,48,112,240,224,0,0,0,0,
930 0,0,127,99,127,99,99,99,99,103,231,230,192,0,0,0,
931 0,0,0,24,24,219,60,231,60,219,24,24,0,0,0,0,
932 0,128,192,224,240,248,254,248,240,224,192,128,0,0,0,0,
933 0,2,6,14,30,62,254,62,30,14,6,2,0,0,0,0,
934 0,0,24,60,126,24,24,24,126,60,24,0,0,0,0,0,
935 0,0,102,102,102,102,102,102,102,0,102,102,0,0,0,0,
936 0,0,127,219,219,219,123,27,27,27,27,27,0,0,0,0,
937 0,124,198,96,56,108,198,198,108,56,12,198,124,0,0,0,
938 0,0,0,0,0,0,0,0,254,254,254,254,0,0,0,0,
939 0,0,24,60,126,24,24,24,126,60,24,126,0,0,0,0,
940 0,0,24,60,126,24,24,24,24,24,24,24,0,0,0,0,
941 0,0,24,24,24,24,24,24,24,126,60,24,0,0,0,0,
942 0,0,0,0,0,24,12,254,12,24,0,0,0,0,0,0,
943 0,0,0,0,0,48,96,254,96,48,0,0,0,0,0,0,
944 0,0,0,0,0,0,192,192,192,254,0,0,0,0,0,0,
945 0,0,0,0,0,40,108,254,108,40,0,0,0,0,0,0,
946 0,0,0,0,16,56,56,124,124,254,254,0,0,0,0,0,
947 0,0,0,0,254,254,124,124,56,56,16,0,0,0,0,0,
948 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
949 0,0,24,60,60,60,24,24,24,0,24,24,0,0,0,0,
950 0,102,102,102,36,0,0,0,0,0,0,0,0,0,0,0,
951 0,0,0,108,108,254,108,108,108,254,108,108,0,0,0,0,
952 24,24,124,198,194,192,124,6,6,134,198,124,24,24,0,0,
953 0,0,0,0,194,198,12,24,48,96,198,134,0,0,0,0,
954 0,0,56,108,108,56,118,220,204,204,204,118,0,0,0,0,
955 0,48,48,48,96,0,0,0,0,0,0,0,0,0,0,0,
956 0,0,12,24,48,48,48,48,48,48,24,12,0,0,0,0,
957 0,0,48,24,12,12,12,12,12,12,24,48,0,0,0,0,
958 0,0,0,0,0,102,60,255,60,102,0,0,0,0,0,0,
959 0,0,0,0,0,24,24,126,24,24,0,0,0,0,0,0,
960 0,0,0,0,0,0,0,0,0,24,24,24,48,0,0,0,
961 0,0,0,0,0,0,0,254,0,0,0,0,0,0,0,0,
962 0,0,0,0,0,0,0,0,0,0,24,24,0,0,0,0,
963 0,0,0,0,2,6,12,24,48,96,192,128,0,0,0,0,
964 0,0,56,108,198,198,214,214,198,198,108,56,0,0,0,0,
965 0,0,24,56,120,24,24,24,24,24,24,126,0,0,0,0,
966 0,0,124,198,6,12,24,48,96,192,198,254,0,0,0,0,
967 0,0,124,198,6,6,60,6,6,6,198,124,0,0,0,0,
968 0,0,12,28,60,108,204,254,12,12,12,30,0,0,0,0,
969 0,0,254,192,192,192,252,6,6,6,198,124,0,0,0,0,
970 0,0,56,96,192,192,252,198,198,198,198,124,0,0,0,0,
971 0,0,254,198,6,6,12,24,48,48,48,48,0,0,0,0,
972 0,0,124,198,198,198,124,198,198,198,198,124,0,0,0,0,
973 0,0,124,198,198,198,126,6,6,6,12,120,0,0,0,0,
974 0,0,0,0,24,24,0,0,0,24,24,0,0,0,0,0,
975 0,0,0,0,24,24,0,0,0,24,24,48,0,0,0,0,
976 0,0,0,6,12,24,48,96,48,24,12,6,0,0,0,0,
977 0,0,0,0,0,126,0,0,126,0,0,0,0,0,0,0,
978 0,0,0,96,48,24,12,6,12,24,48,96,0,0,0,0,
979 0,0,124,198,198,12,24,24,24,0,24,24,0,0,0,0,
980 0,0,0,124,198,198,222,222,222,220,192,124,0,0,0,0,
981 0,0,16,56,108,198,198,254,198,198,198,198,0,0,0,0,
982 0,0,252,102,102,102,124,102,102,102,102,252,0,0,0,0,
983 0,0,60,102,194,192,192,192,192,194,102,60,0,0,0,0,
984 0,0,248,108,102,102,102,102,102,102,108,248,0,0,0,0,
985 0,0,254,102,98,104,120,104,96,98,102,254,0,0,0,0,
986 0,0,254,102,98,104,120,104,96,96,96,240,0,0,0,0,
987 0,0,60,102,194,192,192,222,198,198,102,58,0,0,0,0,
988 0,0,198,198,198,198,254,198,198,198,198,198,0,0,0,0,
989 0,0,60,24,24,24,24,24,24,24,24,60,0,0,0,0,
990 0,0,30,12,12,12,12,12,204,204,204,120,0,0,0,0,
991 0,0,230,102,102,108,120,120,108,102,102,230,0,0,0,0,
992 0,0,240,96,96,96,96,96,96,98,102,254,0,0,0,0,
993 0,0,198,238,254,254,214,198,198,198,198,198,0,0,0,0,
994 0,0,198,230,246,254,222,206,198,198,198,198,0,0,0,0,
995 0,0,124,198,198,198,198,198,198,198,198,124,0,0,0,0,
996 0,0,252,102,102,102,124,96,96,96,96,240,0,0,0,0,
997 0,0,124,198,198,198,198,198,198,214,222,124,12,14,0,0,
998 0,0,252,102,102,102,124,108,102,102,102,230,0,0,0,0,
999 0,0,124,198,198,96,56,12,6,198,198,124,0,0,0,0,
1000 0,0,126,126,90,24,24,24,24,24,24,60,0,0,0,0,
1001 0,0,198,198,198,198,198,198,198,198,198,124,0,0,0,0,
1002 0,0,198,198,198,198,198,198,198,108,56,16,0,0,0,0,
1003 0,0,198,198,198,198,214,214,214,254,238,108,0,0,0,0,
1004 0,0,198,198,108,124,56,56,124,108,198,198,0,0,0,0,
1005 0,0,102,102,102,102,60,24,24,24,24,60,0,0,0,0,
1006 0,0,254,198,134,12,24,48,96,194,198,254,0,0,0,0,
1007 0,0,60,48,48,48,48,48,48,48,48,60,0,0,0,0,
1008 0,0,0,128,192,224,112,56,28,14,6,2,0,0,0,0,
1009 0,0,60,12,12,12,12,12,12,12,12,60,0,0,0,0,
1010 16,56,108,198,0,0,0,0,0,0,0,0,0,0,0,0,
1011 0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,
1012 0,48,24,12,0,0,0,0,0,0,0,0,0,0,0,0,
1013 0,0,0,0,0,120,12,124,204,204,204,118,0,0,0,0,
1014 0,0,224,96,96,120,108,102,102,102,102,124,0,0,0,0,
1015 0,0,0,0,0,124,198,192,192,192,198,124,0,0,0,0,
1016 0,0,28,12,12,60,108,204,204,204,204,118,0,0,0,0,
1017 0,0,0,0,0,124,198,254,192,192,198,124,0,0,0,0,
1018 0,0,28,54,50,48,120,48,48,48,48,120,0,0,0,0,
1019 0,0,0,0,0,118,204,204,204,204,204,124,12,204,120,0,
1020 0,0,224,96,96,108,118,102,102,102,102,230,0,0,0,0,
1021 0,0,24,24,0,56,24,24,24,24,24,60,0,0,0,0,
1022 0,0,6,6,0,14,6,6,6,6,6,6,102,102,60,0,
1023 0,0,224,96,96,102,108,120,120,108,102,230,0,0,0,0,
1024 0,0,56,24,24,24,24,24,24,24,24,60,0,0,0,0,
1025 0,0,0,0,0,236,254,214,214,214,214,198,0,0,0,0,
1026 0,0,0,0,0,220,102,102,102,102,102,102,0,0,0,0,
1027 0,0,0,0,0,124,198,198,198,198,198,124,0,0,0,0,
1028 0,0,0,0,0,220,102,102,102,102,102,124,96,96,240,0,
1029 0,0,0,0,0,118,204,204,204,204,204,124,12,12,30,0,
1030 0,0,0,0,0,220,118,102,96,96,96,240,0,0,0,0,
1031 0,0,0,0,0,124,198,96,56,12,198,124,0,0,0,0,
1032 0,0,16,48,48,252,48,48,48,48,54,28,0,0,0,0,
1033 0,0,0,0,0,204,204,204,204,204,204,118,0,0,0,0,
1034 0,0,0,0,0,198,198,198,198,198,108,56,0,0,0,0,
1035 0,0,0,0,0,198,198,214,214,214,254,108,0,0,0,0,
1036 0,0,0,0,0,198,108,56,56,56,108,198,0,0,0,0,
1037 0,0,0,0,0,198,198,198,198,198,198,126,6,12,248,0,
1038 0,0,0,0,0,254,204,24,48,96,198,254,0,0,0,0,
1039 0,0,14,24,24,24,112,24,24,24,24,14,0,0,0,0,
1040 0,0,24,24,24,24,24,24,24,24,24,24,0,0,0,0,
1041 0,0,112,24,24,24,14,24,24,24,24,112,0,0,0,0,
1042 0,118,220,0,0,0,0,0,0,0,0,0,0,0,0,0,
1043 0,0,0,0,16,56,108,198,198,198,254,0,0,0,0,0,
1044 0,0,60,102,194,192,192,192,192,194,102,60,24,112,0,0,
1045 0,0,204,0,0,204,204,204,204,204,204,118,0,0,0,0,
1046 0,12,24,48,0,124,198,254,192,192,198,124,0,0,0,0,
1047 0,16,56,108,0,120,12,124,204,204,204,118,0,0,0,0,
1048 0,0,204,0,0,120,12,124,204,204,204,118,0,0,0,0,
1049 0,96,48,24,0,120,12,124,204,204,204,118,0,0,0,0,
1050 0,56,108,56,0,120,12,124,204,204,204,118,0,0,0,0,
1051 0,0,0,0,0,124,198,192,192,192,198,124,24,112,0,0,
1052 0,16,56,108,0,124,198,254,192,192,198,124,0,0,0,0,
1053 0,0,198,0,0,124,198,254,192,192,198,124,0,0,0,0,
1054 0,96,48,24,0,124,198,254,192,192,198,124,0,0,0,0,
1055 0,0,102,0,0,56,24,24,24,24,24,60,0,0,0,0,
1056 0,24,60,102,0,56,24,24,24,24,24,60,0,0,0,0,
1057 0,96,48,24,0,56,24,24,24,24,24,60,0,0,0,0,
1058 0,198,0,16,56,108,198,198,254,198,198,198,0,0,0,0,
1059 56,108,56,16,56,108,198,254,198,198,198,198,0,0,0,0,
1060 12,24,0,254,102,98,104,120,104,98,102,254,0,0,0,0,
1061 0,0,0,0,0,236,54,54,126,216,216,110,0,0,0,0,
1062 0,0,62,108,204,204,254,204,204,204,204,206,0,0,0,0,
1063 0,16,56,108,0,124,198,198,198,198,198,124,0,0,0,0,
1064 0,0,198,0,0,124,198,198,198,198,198,124,0,0,0,0,
1065 0,96,48,24,0,124,198,198,198,198,198,124,0,0,0,0,
1066 0,48,120,204,0,204,204,204,204,204,204,118,0,0,0,0,
1067 0,96,48,24,0,204,204,204,204,204,204,118,0,0,0,0,
1068 0,0,198,0,0,198,198,198,198,198,198,126,6,12,120,0,
1069 0,198,0,124,198,198,198,198,198,198,198,124,0,0,0,0,
1070 0,198,0,198,198,198,198,198,198,198,198,124,0,0,0,0,
1071 0,24,24,124,198,192,192,192,198,124,24,24,0,0,0,0,
1072 0,56,108,100,96,240,96,96,96,96,230,252,0,0,0,0,
1073 0,0,102,102,60,24,126,24,126,24,24,24,0,0,0,0,
1074 0,248,204,204,248,196,204,222,204,204,204,198,0,0,0,0,
1075 0,14,27,24,24,24,126,24,24,24,216,112,0,0,0,0,
1076 0,24,48,96,0,120,12,124,204,204,204,118,0,0,0,0,
1077 0,12,24,48,0,56,24,24,24,24,24,60,0,0,0,0,
1078 0,24,48,96,0,124,198,198,198,198,198,124,0,0,0,0,
1079 0,24,48,96,0,204,204,204,204,204,204,118,0,0,0,0,
1080 0,0,118,220,0,220,102,102,102,102,102,102,0,0,0,0,
1081 118,220,0,198,230,246,254,222,206,198,198,198,0,0,0,0,
1082 0,0,60,108,108,62,0,126,0,0,0,0,0,0,0,0,
1083 0,0,56,108,108,56,0,124,0,0,0,0,0,0,0,0,
1084 0,0,48,48,0,48,48,96,192,198,198,124,0,0,0,0,
1085 0,0,0,0,0,0,254,192,192,192,192,0,0,0,0,0,
1086 0,0,0,0,0,0,254,6,6,6,6,0,0,0,0,0,
1087 0,96,224,98,102,108,24,48,96,220,134,12,24,62,0,0,
1088 0,96,224,98,102,108,24,48,102,206,154,63,6,6,0,0,
1089 0,0,24,24,0,24,24,24,60,60,60,24,0,0,0,0,
1090 0,0,0,0,0,54,108,216,108,54,0,0,0,0,0,0,
1091 0,0,0,0,0,216,108,54,108,216,0,0,0,0,0,0,
1092 17,68,17,68,17,68,17,68,17,68,17,68,17,68,17,68,
1093 85,170,85,170,85,170,85,170,85,170,85,170,85,170,85,170,
1094 221,119,221,119,221,119,221,119,221,119,221,119,221,119,221,119,
1095 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
1096 24,24,24,24,24,24,24,248,24,24,24,24,24,24,24,24,
1097 24,24,24,24,24,248,24,248,24,24,24,24,24,24,24,24,
1098 54,54,54,54,54,54,54,246,54,54,54,54,54,54,54,54,
1099 0,0,0,0,0,0,0,254,54,54,54,54,54,54,54,54,
1100 0,0,0,0,0,248,24,248,24,24,24,24,24,24,24,24,
1101 54,54,54,54,54,246,6,246,54,54,54,54,54,54,54,54,
1102 54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,
1103 0,0,0,0,0,254,6,246,54,54,54,54,54,54,54,54,
1104 54,54,54,54,54,246,6,254,0,0,0,0,0,0,0,0,
1105 54,54,54,54,54,54,54,254,0,0,0,0,0,0,0,0,
1106 24,24,24,24,24,248,24,248,0,0,0,0,0,0,0,0,
1107 0,0,0,0,0,0,0,248,24,24,24,24,24,24,24,24,
1108 24,24,24,24,24,24,24,31,0,0,0,0,0,0,0,0,
1109 24,24,24,24,24,24,24,255,0,0,0,0,0,0,0,0,
1110 0,0,0,0,0,0,0,255,24,24,24,24,24,24,24,24,
1111 24,24,24,24,24,24,24,31,24,24,24,24,24,24,24,24,
1112 0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,
1113 24,24,24,24,24,24,24,255,24,24,24,24,24,24,24,24,
1114 24,24,24,24,24,31,24,31,24,24,24,24,24,24,24,24,
1115 54,54,54,54,54,54,54,55,54,54,54,54,54,54,54,54,
1116 54,54,54,54,54,55,48,63,0,0,0,0,0,0,0,0,
1117 0,0,0,0,0,63,48,55,54,54,54,54,54,54,54,54,
1118 54,54,54,54,54,247,0,255,0,0,0,0,0,0,0,0,
1119 0,0,0,0,0,255,0,247,54,54,54,54,54,54,54,54,
1120 54,54,54,54,54,55,48,55,54,54,54,54,54,54,54,54,
1121 0,0,0,0,0,255,0,255,0,0,0,0,0,0,0,0,
1122 54,54,54,54,54,247,0,247,54,54,54,54,54,54,54,54,
1123 24,24,24,24,24,255,0,255,0,0,0,0,0,0,0,0,
1124 54,54,54,54,54,54,54,255,0,0,0,0,0,0,0,0,
1125 0,0,0,0,0,255,0,255,24,24,24,24,24,24,24,24,
1126 0,0,0,0,0,0,0,255,54,54,54,54,54,54,54,54,
1127 54,54,54,54,54,54,54,63,0,0,0,0,0,0,0,0,
1128 24,24,24,24,24,31,24,31,0,0,0,0,0,0,0,0,
1129 0,0,0,0,0,31,24,31,24,24,24,24,24,24,24,24,
1130 0,0,0,0,0,0,0,63,54,54,54,54,54,54,54,54,
1131 54,54,54,54,54,54,54,255,54,54,54,54,54,54,54,54,
1132 24,24,24,24,24,255,24,255,24,24,24,24,24,24,24,24,
1133 24,24,24,24,24,24,24,248,0,0,0,0,0,0,0,0,
1134 0,0,0,0,0,0,0,31,24,24,24,24,24,24,24,24,
1135 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
1136 0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,
1137 240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
1138 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
1139 255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,
1140 0,0,0,0,0,118,220,216,216,216,220,118,0,0,0,0,
1141 0,0,120,204,204,204,216,204,198,198,198,204,0,0,0,0,
1142 0,0,254,198,198,192,192,192,192,192,192,192,0,0,0,0,
1143 0,0,0,0,0,254,108,108,108,108,108,108,0,0,0,0,
1144 0,0,254,198,96,48,24,24,48,96,198,254,0,0,0,0,
1145 0,0,0,0,0,126,216,216,216,216,216,112,0,0,0,0,
1146 0,0,0,0,0,102,102,102,102,102,102,124,96,96,192,0,
1147 0,0,0,0,118,220,24,24,24,24,24,24,0,0,0,0,
1148 0,0,126,24,60,102,102,102,102,60,24,126,0,0,0,0,
1149 0,0,56,108,198,198,254,198,198,198,108,56,0,0,0,0,
1150 0,0,56,108,198,198,198,108,108,108,108,238,0,0,0,0,
1151 0,0,30,48,24,12,62,102,102,102,102,60,0,0,0,0,
1152 0,0,0,0,0,126,219,219,219,126,0,0,0,0,0,0,
1153 0,0,0,3,6,126,219,219,243,126,96,192,0,0,0,0,
1154 0,0,28,48,96,96,124,96,96,96,48,28,0,0,0,0,
1155 0,0,0,124,198,198,198,198,198,198,198,198,0,0,0,0,
1156 0,0,0,0,254,0,0,254,0,0,254,0,0,0,0,0,
1157 0,0,0,0,24,24,126,24,24,0,0,126,0,0,0,0,
1158 0,0,0,48,24,12,6,12,24,48,0,126,0,0,0,0,
1159 0,0,0,12,24,48,96,48,24,12,0,126,0,0,0,0,
1160 0,0,14,27,27,24,24,24,24,24,24,24,24,24,24,24,
1161 24,24,24,24,24,24,24,24,24,216,216,216,112,0,0,0,
1162 0,0,0,0,0,24,0,126,0,24,0,0,0,0,0,0,
1163 0,0,0,0,0,118,220,0,118,220,0,0,0,0,0,0,
1164 0,56,108,108,56,0,0,0,0,0,0,0,0,0,0,0,
1165 0,0,0,0,0,0,0,24,24,0,0,0,0,0,0,0,
1166 0,0,0,0,0,0,0,24,0,0,0,0,0,0,0,0,
1167 0,15,12,12,12,12,12,236,108,108,60,28,0,0,0,0,
1168 0,108,54,54,54,54,54,0,0,0,0,0,0,0,0,0,
1169 0,60,102,12,24,50,126,0,0,0,0,0,0,0,0,0,
1170 0,0,0,0,126,126,126,126,126,126,126,0,0,0,0,0,
1171 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1174 const u8
*de_get_vga_cp437_font_ptr(void)
1176 return vga_cp437_font_data
;
1179 void de_color_to_css(de_color color
, char *buf
, int buflen
)
1184 r
= DE_COLOR_R(color
);
1185 g
= DE_COLOR_G(color
);
1186 b
= DE_COLOR_B(color
);
1188 if(r
%17==0 && g
%17==0 && b
%17==0) {
1189 // Can use short form.
1190 buf
[1] = g_hexchars
[r
/17];
1191 buf
[2] = g_hexchars
[g
/17];
1192 buf
[3] = g_hexchars
[b
/17];
1197 buf
[1] = g_hexchars
[r
/16];
1198 buf
[2] = g_hexchars
[r
%16];
1199 buf
[3] = g_hexchars
[g
/16];
1200 buf
[4] = g_hexchars
[g
%16];
1201 buf
[5] = g_hexchars
[b
/16];
1202 buf
[6] = g_hexchars
[b
%16];
1206 u8
de_sample_nbit_to_8bit(i64 n
, unsigned int x
)
1208 unsigned int maxval
;
1211 if(n
<1 || n
>16) return 0;
1213 if(x
>=maxval
) return 255;
1214 return (u8
)(0.5+((((double)x
)/(double)maxval
)*255.0));
1217 u8
de_scale_63_to_255(u8 x
)
1219 if(x
>=63) return 255;
1220 return (u8
)(0.5+(((double)x
)*(255.0/63.0)));
1223 u8
de_scale_1000_to_255(i64 x
)
1225 if(x
>=1000) return 255;
1227 return (u8
)(0.5+(((double)x
)*(255.0/1000.0)));
1230 u8
de_scale_n_to_255(i64 n
, i64 x
)
1232 if(x
>=n
) return 255;
1234 return (u8
)(0.5+(((double)x
)*(255.0/(double)n
)));
1237 void de_scale_n_to_16bit(int n
, int x_in
, u8
*x_out_hi
, u8
*x_out_lo
)
1242 if(x_in
<0) x_in
= 0;
1243 if(x_in
>n
) x_in
= n
;
1244 tmp1
= ((double)x_in
/ (double)n
) * 65535.0;
1245 tmp2
= (UI
)(tmp1
+ 0.5);
1246 *x_out_hi
= (tmp2
& 0xff00)>>8;
1247 *x_out_lo
= (tmp2
& 0xff);
1250 de_color
de_rgb565_to_888(u32 x
)
1254 cg
= (u8
)((x
>>5)&0x3f);
1256 cr
= (u8
)(0.5+((double)cr
)*(255.0/31.0));
1257 cg
= (u8
)(0.5+((double)cg
)*(255.0/63.0));
1258 cb
= (u8
)(0.5+((double)cb
)*(255.0/31.0));
1259 return DE_MAKE_RGB(cr
, cg
, cb
);
1262 de_color
de_bgr555_to_888(u32 x
)
1265 cb
= (u8
)((x
>>10)&0x1f);
1266 cg
= (u8
)((x
>>5)&0x1f);
1268 cb
= (u8
)(0.5+((double)cb
)*(255.0/31.0));
1269 cg
= (u8
)(0.5+((double)cg
)*(255.0/31.0));
1270 cr
= (u8
)(0.5+((double)cr
)*(255.0/31.0));
1271 return DE_MAKE_RGB(cr
, cg
, cb
);
1274 de_color
de_rgb555_to_888(u32 x
)
1277 cr
= (u8
)((x
>>10)&0x1f);
1278 cg
= (u8
)((x
>>5)&0x1f);
1280 cr
= (u8
)(0.5+((double)cr
)*(255.0/31.0));
1281 cg
= (u8
)(0.5+((double)cg
)*(255.0/31.0));
1282 cb
= (u8
)(0.5+((double)cb
)*(255.0/31.0));
1283 return DE_MAKE_RGB(cr
, cg
, cb
);
1286 char de_byte_to_printable_char(u8 b
)
1288 if(b
>=32 && b
<=126) return (char)b
;
1292 // This function has been largely replaced by other functions, and should
1293 // rarely be used. See the comment in the header file.
1294 // s1 is not NUL terminated, but s2 will be.
1295 // s2_size includes the NUL terminator.
1296 // Supported conv_flags: DE_CONVFLAG_STOP_AT_NUL, DE_CONVFLAG_ALLOW_HL
1297 // src_encoding: Only DE_ENCODING_ASCII is supported.
1298 void de_bytes_to_printable_sz(const u8
*s1
, i64 s1_len
,
1299 char *s2
, i64 s2_size
, unsigned int conv_flags
, de_ext_encoding src_ee
)
1303 de_ext_encoding src_encoding
= DE_EXTENC_GET_BASE(src_ee
);
1305 if(src_encoding
!=DE_ENCODING_ASCII
) {
1310 for(i
=0; i
<s1_len
; i
++) {
1311 int is_printable
= 0;
1313 if(s1
[i
]=='\0' && (conv_flags
& DE_CONVFLAG_STOP_AT_NUL
)) {
1317 if(s1
[i
]>=32 && s1
[i
]<=126) {
1322 if(s2_pos
< s2_size
-1) {
1323 s2
[s2_pos
++] = (char)s1
[i
];
1326 else if(conv_flags
& DE_CONVFLAG_ALLOW_HL
) {
1327 if(s2_pos
< s2_size
-6) {
1328 s2
[s2_pos
++] = 0x01; // DE_CODEPOINT_HL
1330 s2
[s2_pos
++] = de_get_hexcharUC((int)(s1
[i
]/16));
1331 s2
[s2_pos
++] = de_get_hexcharUC((int)(s1
[i
]%16));
1333 s2
[s2_pos
++] = 0x02; // DE_CODEPOINT_UNHL
1337 if(s2_pos
< s2_size
-1) {
1346 void de_write_codepoint_to_html(deark
*c
, dbuf
*f
, de_rune ch
)
1348 int e
; // How to encode this codepoint
1350 if(ch
<0 || ch
>0x10ffff || ch
==DE_CODEPOINT_INVALID
) ch
=0xfffd;
1352 if(ch
=='&' || ch
=='<' || ch
=='>') {
1353 e
= 1; // HTML entity
1355 else if(ch
>=32 && ch
<=126) {
1358 else if(c
->ascii_html
) {
1359 e
= 1; // HTML entity
1366 dbuf_writebyte(f
, (u8
)ch
);
1369 dbuf_write_uchar_as_utf8(f
, ch
);
1372 dbuf_printf(f
, "&#%d;", (int)ch
);
1376 struct de_encmap_item
{
1377 unsigned int reserved
;
1379 const char *encname
;
1382 static const struct de_encmap_item de_encmap_arr
[] = {
1383 { 0x01, DE_ENCODING_ASCII
, "ascii" },
1384 { 0x01, DE_ENCODING_UTF8
, "utf8" },
1385 { 0x01, DE_ENCODING_LATIN1
, "latin1" },
1386 { 0x01, DE_ENCODING_LATIN2
, "latin2" },
1387 { 0x01, DE_ENCODING_CP437
, "cp437" },
1388 { 0x01, DE_ENCODING_WINDOWS1250
, "windows1250" },
1389 { 0x01, DE_ENCODING_WINDOWS1251
, "windows1251" },
1390 { 0x01, DE_ENCODING_WINDOWS1252
, "windows1252" },
1391 { 0x01, DE_ENCODING_WINDOWS1253
, "windows1253" },
1392 { 0x01, DE_ENCODING_WINDOWS1254
, "windows1254" },
1393 { 0x01, DE_ENCODING_WINDOWS874
, "windows874" },
1394 { 0x01, DE_ENCODING_MACROMAN
, "macroman" },
1395 { 0x01, DE_ENCODING_PALM
, "palm" },
1396 { 0x01, DE_ENCODING_RISCOS
, "riscos" },
1397 { 0x01, DE_ENCODING_PETSCII
, "petscii" },
1398 { 0x01, DE_ENCODING_ATARIST
, "atarist" },
1399 { 0x01, DE_ENCODING_APPLEII
, "appleii" },
1400 { 0x01, DE_ENCODING_ROT13
, "rot13" },
1401 { 0x01, DE_ENCODING_UTF16BE
, "utf16be" },
1402 { 0x01, DE_ENCODING_UTF16LE
, "utf16le" }
1405 de_encoding
de_encoding_name_to_code(const char *encname
)
1409 for(k
=0; k
<DE_ARRAYCOUNT(de_encmap_arr
); k
++) {
1410 if(!de_strcasecmp(encname
, de_encmap_arr
[k
].encname
)) {
1411 return de_encmap_arr
[k
].n
;
1414 return DE_ENCODING_UNKNOWN
;
1417 struct de_encmapwin_item
{
1418 unsigned int flags
; // 0x1=supported
1421 const char *encname
;
1422 const char *encname_note
;
1425 static const struct de_encmapwin_item de_encmapwin_arr
[] = {
1426 { 0x01, 1200, DE_ENCODING_UTF16LE
, "UTF-16LE", NULL
},
1427 { 0x01, 1250, DE_ENCODING_WINDOWS1250
, "Windows-1250", "Central/Eastern European" },
1428 { 0x01, 1251, DE_ENCODING_WINDOWS1251
, "Windows-1251", "Cyrillic" },
1429 { 0x01, 1252, DE_ENCODING_WINDOWS1252
, "Windows-1252", NULL
},
1430 { 0x01, 1253, DE_ENCODING_WINDOWS1253
, "Windows-1253", "Greek" },
1431 { 0x01, 1254, DE_ENCODING_WINDOWS1254
, "Windows-1254", "Turkish" },
1432 { 0x01, 10000, DE_ENCODING_MACROMAN
, "MacRoman", NULL
},
1433 { 0x01, 65001, DE_ENCODING_UTF8
, "UTF-8", NULL
},
1434 { 0x01, 874, DE_ENCODING_WINDOWS874
, "Windows-874", "Thai" },
1435 { 0x00, 932, DE_ENCODING_UNKNOWN
, "Windows-932", "Japanese" },
1436 { 0x00, 936, DE_ENCODING_UNKNOWN
, "Windows-936", "simplified Chinese" },
1437 { 0x00, 1255, DE_ENCODING_UNKNOWN
, "Windows-1255", "Hebrew" },
1438 { 0x00, 1256, DE_ENCODING_UNKNOWN
, "Windows-1256", "Arabic" },
1439 { 0x00, 1257, DE_ENCODING_UNKNOWN
, "Windows-1257", "Baltic" },
1440 { 0x00, 1258, DE_ENCODING_UNKNOWN
, "Windows-1258", "Vietnamese" }
1443 // Returns a DE_ENCODING_* code.
1444 // Returns DE_ENCODING_UNKNOWN if unsupported or unknown.
1445 // encname can be NULL.
1447 // 0x1: If encoding is known but unsupported, append "(unsupported)" to the
1449 de_encoding
de_windows_codepage_to_encoding(deark
*c
, int wincodepage
,
1450 char *encname
, size_t encname_len
, unsigned int flags
)
1453 const struct de_encmapwin_item
*cpinfo
= NULL
;
1455 for(k
=0; k
<DE_ARRAYCOUNT(de_encmapwin_arr
); k
++) {
1456 if(de_encmapwin_arr
[k
].wincodepage
== wincodepage
) {
1457 cpinfo
= &de_encmapwin_arr
[k
];
1463 // Code page is known, though not necessarily supported.
1466 if(cpinfo
->encname_note
) {
1467 de_snprintf(note_tmp
, sizeof(note_tmp
), " (%s)", cpinfo
->encname_note
);
1472 de_snprintf(encname
, encname_len
, "%s%s%s", cpinfo
->encname
, note_tmp
,
1473 ((cpinfo
->flags
&0x1)==0 && (flags
&0x1)!=0)?" (unsupported)":"");
1475 return (cpinfo
->flags
&0x1) ? cpinfo
->enc
: DE_ENCODING_UNKNOWN
;
1479 de_strlcpy(encname
, "?", encname_len
);
1481 return DE_ENCODING_UNKNOWN
;
1484 void de_decode_base16(deark
*c
, dbuf
*inf
, i64 pos1
, i64 len
,
1485 dbuf
*outf
, unsigned int flags
)
1494 struct base16_ctx
*d
= NULL
;
1496 d
= de_malloc(c
, sizeof(struct base16_ctx
));
1499 while(pos
<pos1
+len
) {
1500 b
= dbuf_getbyte_p(inf
, &pos
);
1501 if(b
>='0' && b
<='9') {
1502 d
->cbuf
[d
->cbuf_count
++] = b
-48;
1504 else if(b
>='A' && b
<='F') {
1505 d
->cbuf
[d
->cbuf_count
++] = b
-55;
1507 else if(b
>='a' && b
<='f') {
1508 d
->cbuf
[d
->cbuf_count
++] = b
-87;
1510 else if(b
==9 || b
==10 || b
==13 || b
==32) {
1511 ; // ignore whitespace
1515 de_warn(c
, "Bad hex character(s) found (offset %d)", (int)pos
);
1520 if(d
->cbuf_count
>=2) {
1521 dbuf_writebyte(outf
, (d
->cbuf
[0]<<4)|(d
->cbuf
[1]));
1526 if(d
->cbuf_count
>0) {
1527 de_warn(c
, "Unexpected end of hex data");