1 // This file is part of Deark.
2 // Copyright (C) 2018 Jason Summers
3 // See the file COPYING for terms of use.
7 #include <deark-config.h>
8 #include <deark-private.h>
9 DE_DECLARE_MODULE(de_module_unifont_hex
);
11 struct de_linereader
{
16 static struct de_linereader
*de_linereader_create(deark
*c
, dbuf
*f
)
18 struct de_linereader
*lr
;
19 lr
= de_malloc(c
, sizeof(struct de_linereader
));
24 static void de_linereader_destroy(deark
*c
, struct de_linereader
*lr
)
30 // TODO: Make the linereader more efficient and flexible, and make
31 // it a standard library function.
32 static int de_linereader_readnextline(deark
*c
, struct de_linereader
*lr
,
33 char *buf
, size_t buf_len
, unsigned int flags
)
41 ret
= dbuf_find_line(lr
->f
, lr
->f_pos
, &content_len
, &total_len
);
43 if(content_len
> (i64
)buf_len
-1) {
44 lr
->f_pos
+= total_len
;
47 dbuf_read(lr
->f
, (u8
*)buf
, lr
->f_pos
, content_len
);
48 buf
[content_len
] = '\0';
49 lr
->f_pos
+= total_len
;
53 static void decode_fontdata(deark
*c
, const char *hexdata
,
54 struct de_bitmap_font_char
*ch
)
60 ndstbytes
= ch
->rowspan
*ch
->height
;
65 h0
= de_decode_hex_digit((unsigned char)hexdata
[srcpos
++], &errorflag
);
67 h1
= de_decode_hex_digit((unsigned char)hexdata
[srcpos
++], &errorflag
);
69 ch
->bitmap
[dstpos
++] = (h0
<<4)|h1
;
70 if(dstpos
>=ndstbytes
) break;
74 static void de_run_unifont_hex(deark
*c
, de_module_params
*mparams
)
76 struct de_bitmap_font
*font
= NULL
;
77 i64 char_array_numalloc
= 0;
79 struct de_linereader
*lr
= NULL
;
82 font
= de_create_bitmap_font(c
);
83 font
->has_unicode_codepoints
= 1;
84 font
->prefer_unicode
= 1;
85 font
->nominal_height
= 16;
86 char_array_numalloc
= 1024;
87 font
->char_array
= de_mallocarray(c
, char_array_numalloc
, sizeof(struct de_bitmap_font_char
));
89 lr
= de_linereader_create(c
, c
->infile
);
91 while(de_linereader_readnextline(c
, lr
, linebuf
, sizeof(linebuf
), 0)) {
93 struct de_bitmap_font_char
*ch
;
95 char *dptr
; // Pointer into linebuf, to the char after the ":"
97 if(font
->num_chars
>=17*65536) goto done
;
99 idx
= font
->num_chars
;
100 if(idx
>= char_array_numalloc
) {
101 i64 new_numalloc
= char_array_numalloc
*2;
102 font
->char_array
= de_reallocarray(c
, font
->char_array
,
103 char_array_numalloc
, sizeof(struct de_bitmap_font_char
),
105 char_array_numalloc
= new_numalloc
;
107 ch
= &font
->char_array
[idx
];
109 dptr
= de_strchr(linebuf
, ':');
114 fdata_len
= (i64
)de_strlen(dptr
);
115 ch
->codepoint_unicode
= (i32
)de_strtoll(linebuf
, NULL
, 16);
116 if(ch
->codepoint_unicode
<0 || ch
->codepoint_unicode
>=17*65536) goto done
;
118 ch
->width
= (int)((fdata_len
/32)*8);
120 de_dbg2(c
, "char[%d] U+%04X %d"DE_CHAR_TIMES
"%d",
121 (int)font
->num_chars
, (unsigned int)ch
->codepoint_unicode
,
122 ch
->width
, ch
->height
);
123 if(ch
->width
<8 || ch
->width
>32) goto done
;
124 ch
->rowspan
= (ch
->width
+7)/8;
125 ch
->bitmap
= de_malloc(c
, ch
->rowspan
* ch
->height
);
126 decode_fontdata(c
, dptr
, ch
);
129 if(ch
->width
> font
->nominal_width
) {
130 font
->nominal_width
= ch
->width
;
134 de_dbg(c
, "number of characters: %d", (int)font
->num_chars
);
135 if(font
->num_chars
<1) goto done
;
136 if(font
->nominal_width
<1) goto done
;
138 de_font_bitmap_font_to_image(c
, font
, NULL
, 0);
143 de_err(c
, "Error parsing HEX font file (offset %"I64_FMT
")", lr
->f_pos
);
145 de_linereader_destroy(c
, lr
);
147 if(font
->char_array
) {
149 for(k
=0; k
<font
->num_chars
; k
++) {
150 de_free(c
, font
->char_array
[k
].bitmap
);
152 de_free(c
, font
->char_array
);
154 font
->char_array
= NULL
;
155 de_destroy_bitmap_font(c
, font
);
159 void de_module_unifont_hex(deark
*c
, struct deark_module_info
*mi
)
161 mi
->id
= "unifont_hex";
162 mi
->desc
= "GNU Unifont HEX font";
163 mi
->run_fn
= de_run_unifont_hex
;