52#define PNG_MAGIC "\x89PNG\x0D\x0A\x1A\x0A"
53#define PS_MAGIC "%!PS-Adobe-"
55#define GIF_MAGIC "GIF8"
56#define JPEG_MAGIC "\xFF\xD8\xFF"
57#define PDF_MAGIC "%PDF-"
58#define EPS_MAGIC "\xC5\xD0\xD3\xC6"
59#define XML_MAGIC "<?xml"
60#define SVG_MAGIC "<svg"
61#define RIFF_MAGIC "RIFF"
62#define WEBP_MAGIC "WEBP"
63#define ICO_MAGIC "\x00\x00\x01\x00"
129 char header[
HDRLEN] = {0};
140 int c = fgetc(us->
f);
143 }
else if (c ==
'>') {
150 if (fread(tag, 1,
sizeof(tag), us->
f) !=
sizeof(tag)) {
158 int c = fgetc(us->
f);
162 memmove(&tag[0], &tag[1],
sizeof(tag) - 1);
163 tag[
sizeof(tag) - 1] = (
char)c;
187 for (
size_t i = 0; i < sz; i++) {
191 value |= (unsigned)ch << 8 * i;
193 if (value > INT_MAX) {
204 for (
size_t i = 0; i < sz; i++) {
209 value |= (unsigned)ch;
211 if (value > INT_MAX) {
219 if (strcmp(u,
"in") == 0)
221 if (strcmp(u,
"px") == 0)
223 if (strcmp(u,
"pc") == 0)
225 if (strcmp(u,
"pt") == 0 ||
226 strcmp(u,
"\"") == 0)
229 if (strcmp(u,
"cm") == 0)
231 if (strcmp(u,
"mm") == 0)
244 for (
size_t i = 0;
s[i] !=
'\0';) {
253 if (
s[i] ==
'=' &&
s[i + 1] ==
'"') {
257 while (
s[i] !=
'"' &&
s[i] !=
'\0') {
293 int c = fgetc(us->
f);
297 }
else if (c ==
'\n') {
303 const char *re_string =
agxbuse(&line);
310 if (sscanf(value,
"%lf%2s", &n, u) == 2) {
312 }
else if (sscanf(value,
"%lf", &n) == 1) {
320 if (sscanf(value,
"%lf%2s", &n, u) == 2) {
322 }
else if (sscanf(value,
"%lf", &n) == 1) {
331 if (sscanf(value,
"%*f %*f %lf %lf", &w, &h) == 2) {
354 assert(w >= 0 && w <= INT_MAX);
356 assert(h >= 0 && h <= INT_MAX);
365 fseek(us->
f, 16, SEEK_SET);
376 fseek(us->
f, 6, SEEK_SET);
387 fseek(us->
f, 15, SEEK_SET);
388 if (fgetc(us->
f) ==
'X') {
389 fseek(us->
f, 24, SEEK_SET);
395 fseek(us->
f, 26, SEEK_SET);
407 fseek(us->
f, 6, SEEK_SET);
415 int size_x_msw, size_x_lsw, size_y_msw, size_y_lsw;
418 fseek(us->
f, 16, SEEK_SET);
423 us->
w = size_x_msw << 16 | size_x_lsw;
424 us->
h = size_y_msw << 16 | size_y_lsw;
429 int marker,
length, size_x, size_y;
434 static const unsigned char standalone_markers[] = {
436 0xd0, 0xd1, 0xd2, 0xd3,
437 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
463 if (memchr(standalone_markers, marker,
sizeof(standalone_markers)))
467 if (marker == 0xc0) {
469 if (fseek(us->
f, 3, SEEK_CUR) == 0 &&
481 if (marker == 0xc2) {
483 if (fseek(us->
f, 3, SEEK_CUR) != 0)
499 fseek(us->
f,
length - 2, SEEK_CUR);
511 while (fgets(line,
sizeof(line), us->
f)) {
520 if (!(linep = strstr(line,
"%%BoundingBox:")))
522 if (sscanf(linep,
"%%%%BoundingBox: %d %d %d %d", &lx, &ly, &ux, &uy) ==
543 const int c = getc(
str->fp);
548 (void)ungetc(c,
str->fp);
556 double d = strtod(
tok, &endp);
567 const int c = getc(
str->fp);
573 (void)ungetc(c,
str->fp);
582 if (getc(
str->fp) !=
'[')
608static bool fstr(FILE *f,
const char *needle) {
610 assert(needle !=
NULL);
614 for (
size_t i = 0; needle[i] !=
'\0'; ++i) {
615 for (
size_t j = i + 1; needle[j] !=
'\0'; ++j) {
616 assert(needle[i] != needle[j]);
620 for (
size_t offset = 0;;) {
621 if (needle[offset] ==
'\0') {
624 const int c = getc(f);
628 if (needle[offset] == c) {
630 }
else if (needle[0] == c) {
641 static const char KEY[] =
"/MediaBox";
694#define MAX_USERSHAPE_FILES_OPEN 50
696 static int usershape_files_open_cnt;
712 agwarningf(
"%s while opening %s\n", strerror(errno), fn);
718 usershape_files_open_cnt++;
762 "\"%s\" was not found as a file or as a shape library member\n",
817 dpi.
x = dpi.
y = us->
dpi;
832 static char *oldpath;
836 if (!name || (*name ==
'\0')) {
852 dpi.
x = dpi.
y = DEFAULT_DPI;
size_t match(char *str, char *pat)
static void agxbfree(agxbuf *xb)
free any malloced resources
static WUR char * agxbuse(agxbuf *xb)
static int agxbputc(agxbuf *xb, char c)
add character to buffer
Memory allocation wrappers that exit on failure.
static void * gv_alloc(size_t size)
CDT_API Dtmethod_t * Dttree
CDT_API int dtclose(Dt_t *)
CDT_API Dt_t * dtopen(Dtdisc_t *, Dtmethod_t *)
const char * safefile(const char *filename)
static Extype_t length(Exid_t *rhs, Exdisc_t *disc)
void agwarningf(const char *fmt,...)
int agstrfree(Agraph_t *, const char *, bool is_html)
char * agstrdup(Agraph_t *, const char *)
returns a pointer to a reference-counted copy of the argument string, creating one if necessary
bool gvusershape_file_access(usershape_t *us)
replacements for ctype.h functions
static bool gv_islower(int c)
static bool gv_isdigit(int c)
static bool gv_isalpha(int c)
static bool gv_isspace(int c)
FILE * gv_fopen(const char *filename, const char *mode)
wrapper around fopen for internal library usage
static void ico_size(usershape_t *us)
static void freeUsershape(usershape_t *us)
#define MAX_USERSHAPE_FILES_OPEN
static bool get_int_msb_first(FILE *f, size_t sz, int *val)
shape_desc * find_user_shape(const char *)
static bool get_int_lsb_first(FILE *f, size_t sz, int *val)
static char * getNum(stream_t *str)
static void skipWS(stream_t *str)
static Dtdisc_t ImageDictDisc
static int find_attribute(const char *s, match_t *result)
static void webp_size(usershape_t *us)
static bool fstr(FILE *f, const char *needle)
usershape_t * gvusershape_find(const char *name)
void gvusershape_file_release(usershape_t *us)
point gvusershape_size(graph_t *g, char *name)
point gvusershape_size_dpi(usershape_t *us, pointf dpi)
static int boxof(stream_t *str, boxf *bp)
static void jpeg_size(usershape_t *us)
static usershape_t * gvusershape_open(const char *name)
static int bboxPDF(FILE *fp, boxf *bp)
static knowntype_t knowntypes[]
static void png_size(usershape_t *us)
static void gif_size(usershape_t *us)
static imagetype_t imagetype(usershape_t *us)
static int scanNum(char *tok, double *dp)
static Dict_t * ImageDict
static double svg_units_convert(double n, char *u)
static void pdf_size(usershape_t *us)
static void ps_size(usershape_t *us)
static void svg_size(usershape_t *us)
static void bmp_size(usershape_t *us)
static void usershape_close(void *p)
textitem scanner parser str
C analog of C++’s std::optional
static void optional_double_set(optional_double_t *me, double value)
static double optional_double_value_or(optional_double_t me, double fallback)
a container that may or may not contain a double value
double value
the value if has_value is true
bool has_value
does this have a value?
a non-owning string reference
const char * data
start of the pointed to string
size_t size
extent of the string in bytes
void(* datafree)(usershape_t *us)
Non-owning string references.
static bool strview_str_eq(strview_t a, const char *b)
compare a string reference to a string for equality
static char * strview_str(strview_t source)
make a heap-allocated string from this string view
static tok_t tok(const char *input, const char *separators)
begin tokenization of a new string
graphs, nodes and edges info: Agraphinfo_t, Agnodeinfo_t and Agedgeinfo_t