48#define PNG_MAGIC "\x89PNG\x0D\x0A\x1A\x0A"
49#define PS_MAGIC "%!PS-Adobe-"
51#define GIF_MAGIC "GIF8"
52#define JPEG_MAGIC "\xFF\xD8\xFF"
53#define PDF_MAGIC "%PDF-"
54#define EPS_MAGIC "\xC5\xD0\xD3\xC6"
55#define XML_MAGIC "<?xml"
56#define SVG_MAGIC "<svg"
57#define RIFF_MAGIC "RIFF"
58#define WEBP_MAGIC "WEBP"
59#define ICO_MAGIC "\x00\x00\x01\x00"
125 char header[
HDRLEN] = {0};
136 int c = fgetc(us->
f);
139 }
else if (c ==
'>') {
146 if (fread(tag, 1,
sizeof(tag), us->
f) !=
sizeof(tag)) {
154 int c = fgetc(us->
f);
158 memmove(&tag[0], &tag[1],
sizeof(tag) - 1);
159 tag[
sizeof(tag) - 1] = (
char)c;
181 for (
size_t i = 0; i < sz; i++) {
182 const int ch = fgetc(f);
185 value |= (unsigned)ch << 8 * i;
187 if (value > INT_MAX) {
196 for (
size_t i = 0; i < sz; i++) {
197 const int ch = fgetc(f);
201 value |= (unsigned)ch;
203 if (value > INT_MAX) {
235 for (
size_t i = 0;
s[i] !=
'\0';) {
244 if (
s[i] ==
'=' &&
s[i + 1] ==
'"') {
248 while (
s[i] !=
'"' &&
s[i] !=
'\0') {
284 int c = fgetc(us->
f);
288 }
else if (c ==
'\n') {
294 const char *re_string =
agxbuse(&line);
301 if (sscanf(value,
"%lf%2s", &n, u) == 2) {
303 }
else if (sscanf(value,
"%lf", &n) == 1) {
311 if (sscanf(value,
"%lf%2s", &n, u) == 2) {
313 }
else if (sscanf(value,
"%lf", &n) == 1) {
322 if (sscanf(value,
"%*f %*f %lf %lf", &w, &h) == 2) {
345 assert(w >= 0 && w <= INT_MAX);
347 assert(h >= 0 && h <= INT_MAX);
356 fseek(us->
f, 16, SEEK_SET);
367 fseek(us->
f, 6, SEEK_SET);
378 fseek(us->
f, 15, SEEK_SET);
379 if (fgetc(us->
f) ==
'X') {
380 fseek(us->
f, 24, SEEK_SET);
386 fseek(us->
f, 26, SEEK_SET);
398 fseek(us->
f, 6, SEEK_SET);
406 int size_x_msw, size_x_lsw, size_y_msw, size_y_lsw;
409 fseek(us->
f, 16, SEEK_SET);
414 us->
w = size_x_msw << 16 | size_x_lsw;
415 us->
h = size_y_msw << 16 | size_y_lsw;
420 int marker,
length, size_x, size_y;
425 static const unsigned char standalone_markers[] = {
427 0xd0, 0xd1, 0xd2, 0xd3,
428 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
454 if (memchr(standalone_markers, marker,
sizeof(standalone_markers)))
458 if (marker == 0xc0) {
460 if (fseek(us->
f, 3, SEEK_CUR) == 0 &&
472 if (marker == 0xc2) {
474 if (fseek(us->
f, 3, SEEK_CUR) != 0)
490 fseek(us->
f,
length - 2, SEEK_CUR);
502 while (fgets(line,
sizeof(line), us->
f)) {
511 if (!(linep = strstr(line,
"%%BoundingBox:")))
513 if (sscanf(linep,
"%%%%BoundingBox: %d %d %d %d", &lx, &ly, &ux, &uy) ==
534 const int c = getc(
str->fp);
539 (void)ungetc(c,
str->fp);
547 double d = strtod(
tok, &endp);
558 const int c = getc(
str->fp);
564 (void)ungetc(c,
str->fp);
573 if (getc(
str->fp) !=
'[')
599static bool fstr(FILE *f,
const char *needle) {
601 assert(needle !=
NULL);
605 for (
size_t i = 0; needle[i] !=
'\0'; ++i) {
606 for (
size_t j = i + 1; needle[j] !=
'\0'; ++j) {
607 assert(needle[i] != needle[j]);
611 for (
size_t offset = 0;;) {
612 if (needle[offset] ==
'\0') {
615 const int c = getc(f);
619 if (needle[offset] == c) {
621 }
else if (needle[0] == c) {
632 static const char KEY[] =
"/MediaBox";
682#define MAX_USERSHAPE_FILES_OPEN 50
684 static int usershape_files_open_cnt;
700 agwarningf(
"%s while opening %s\n", strerror(errno), fn);
706 usershape_files_open_cnt++;
750 "\"%s\" was not found as a file or as a shape library member\n",
800 return (
point){.
x = -1, .y = -1};
803 dpi.
x = dpi.
y = us->
dpi;
815 static char *oldpath;
818 if (!name || (*name ==
'\0')) {
819 return (
point){.
x = -1, .y = -1};
833 dpi.
x = dpi.
y = DEFAULT_DPI;
size_t match(char *str, char *pat)
Dynamically expanding string buffers.
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)
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)
shape_desc * find_user_shape(const char *)
static bool streq(const char *a, const char *b)
are a and b equal?
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