summaryrefslogtreecommitdiffstats
path: root/sbix.c
blob: 5bc67ca229a16bfed3732294912d580d024e0f89 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* See LICENSE file for copyright and license details. */
#include "common.h"


int
libparsesfnt_parse_sbix(
			const char *data, size_t size,
			struct libparsesfnt_sbix *infop,
			const struct libparsesfnt_tabdir_entry *tag)
{
	return PARSE(LIBPARSESFNT_SBIX__, tag->offset, 0, 0, 0, 1, tag);
}


int
libparsesfnt_parse_sbix_v1_strike_offset_entries(
			const char *data, size_t size,
			uint32_t *infop,
			const struct libparsesfnt_tabdir_entry *tag,
			size_t first, size_t count)
{
	return PARSE("4", tag->offset, 8, 0, first, count, tag);
}


int
libparsesfnt_parse_sbix_v1_strike_entry(
			const char *data, size_t size,
			struct libparsesfnt_sbix_v1_strike_entry *infop,
			const struct libparsesfnt_tabdir_entry *tag, size_t strike_offset)
{
	return PARSE(LIBPARSESFNT_SBIX_V1_STRIKE_ENTRY__, tag->offset, strike_offset, 0, 0, 1, tag);
}


int
libparsesfnt_parse_sbix_v1_glyph_data_offset_entries(
			const char *data, size_t size,
			uint32_t *infop,
			const struct libparsesfnt_tabdir_entry *tag, size_t strike_offset,
			size_t first, size_t count)
{
	return PARSE("4", tag->offset, strike_offset, 4, first, count, tag);
}


int
libparsesfnt_parse_sbix_v1_glyph_data_entry(
			const char *data, size_t size,
			struct libparsesfnt_sbix_v1_glyph_data_entry *infop,
			const struct libparsesfnt_tabdir_entry *tag,
			  size_t strike_offset, size_t glyph_data_offset, size_t next_glyphs_data_offset)
{
	int ret;
	size_t image_data_length;
	if (next_glyphs_data_offset < glyph_data_offset)
		goto ebfont;
	image_data_length = next_glyphs_data_offset - glyph_data_offset;
	if (!image_data_length) {
		errno = EINVAL;
		return -1;
	} else if (image_data_length < 8) {
		goto ebfont;
	}
	ret = PARSE(LIBPARSESFNT_SBIX_V1_GLYPH_DATA_ENTRY__, tag->offset, strike_offset, glyph_data_offset, 0, 1, tag);
	if (!ret) {
		infop->libparsesfnt_image_data_offset = (size_t)tag->offset + (size_t)strike_offset + (size_t)glyph_data_offset + 8;
		infop->libparsesfnt_image_data_length = image_data_length - 8;
		if (infop->libparsesfnt_image_data_length > size - infop->libparsesfnt_image_data_offset)
			goto ebfont;
	}
	return ret;

ebfont:
	errno = EBFONT;
	return -1;
}


int
libparsesfnt_parse_sbix_v1_image_data_dupe(
			const char *data, size_t size,
			struct libparsesfnt_sbix_v1_image_data_dupe *infop,
			const struct libparsesfnt_sbix_v1_glyph_data_entry *glyph_data)
{
	return PARSE(LIBPARSESFNT_SBIX_V1_IMAGE_DATA_DUPE__, glyph_data->libparsesfnt_image_data_offset, 0, 0, 0, 1, NULL);
}


int
libparsesfnt_parse_sbix_v1_image_data_mask(
			const char *data, size_t size,
			struct libparsesfnt_sbix_v1_image_data_mask *infop,
			const struct libparsesfnt_sbix_v1_glyph_data_entry *glyph_data)
{
	int ret;
	if (glyph_data->libparsesfnt_image_data_length < 8 ||
	    glyph_data->libparsesfnt_image_data_offset > SIZE_MAX - 8)
			goto ebfont;
	ret = PARSE(LIBPARSESFNT_SBIX_V1_IMAGE_DATA_MASK__, glyph_data->libparsesfnt_image_data_offset, 0, 0, 0, 1, NULL);
	if (!ret) {
		infop->libparsesfnt_image_data_offset = glyph_data->libparsesfnt_image_data_offset + 8;
		infop->libparsesfnt_image_data_length = glyph_data->libparsesfnt_image_data_length - 8;
		if (infop->libparsesfnt_image_data_length > size - infop->libparsesfnt_image_data_offset)
			goto ebfont;
	}
	return ret;

ebfont:
	errno = EBFONT;
	return -1;
}


int
libparsesfnt_parse_sbix_v1_mask(
			const char *data, size_t size,
			struct libparsesfnt_sbix_v1_mask *infop,
			const struct libparsesfnt_tabdir_entry *tag,
			  const struct libparsesfnt_sbix_v1_image_data_mask *image_data)
{
	int ret;
	ret = PARSE(LIBPARSESFNT_SBIX_V1_MASK__, tag->offset, image_data->mask_offset, 0, 0, 1, NULL);
	if (!ret) {
		infop->libparsesfnt_mask_offset = (size_t)tag->offset + (size_t)image_data->mask_offset + 16;
		if ((size_t)infop->mask_length > size - infop->libparsesfnt_mask_offset) {
			errno = EBFONT;
			return -1;
		}
	}
	return ret;
}