3 Copyright 2006-2013 Taco Hoekwater <taco@luatex.org>
5 This file is part of LuaTeX.
7 LuaTeX is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2 of the License, or (at your
10 option) any later version.
12 LuaTeX is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License along
18 with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
21 #include "lua/luatex-api.h"
27 #define img_types_max 7
29 const char *img_types
[] = {
41 static void copy_image(lua_State
* L
, lua_Number scale
)
43 image
*a
, **aa
, *b
, **bb
;
45 if (lua_gettop(L
) == 0)
46 luaL_error(L
, "img.copy needs an image as argument");
47 aa
= (image
**) luaL_checkudata(L
, 1, TYPE_IMG
); /* a */
48 lua_pop(L
, 1); /* - */
50 bb
= (image
**) lua_newuserdata(L
, sizeof(image
*)); /* b */
51 luaL_getmetatable(L
, TYPE_IMG
); /* m b */
52 lua_setmetatable(L
, -2); /* b */
53 b
= *bb
= new_image();
54 if (!is_wd_running(a
))
55 img_width(b
) = do_zround(img_width(a
) * scale
);
56 if (!is_ht_running(a
))
57 img_height(b
) = do_zround(img_height(a
) * scale
);
58 if (!is_dp_running(a
))
59 img_depth(b
) = do_zround(img_depth(a
) * scale
);
60 img_transform(b
) = img_transform(a
);
61 img_dict(b
) = img_dict(a
);
62 if (img_dictref(a
) != LUA_NOREF
) {
63 lua_rawgeti(L
, LUA_REGISTRYINDEX
, img_dictref(a
)); /* ad b */
64 img_dictref(b
) = luaL_ref(L
, LUA_REGISTRYINDEX
); /* b */
67 } else if (img_state(img_dict(a
)) < DICT_REFERED
) {
68 luaL_error(L
, "img.copy needs an proper image as argument");
72 static void lua_to_image(lua_State
* L
, image
* a
, image_dict
* d
);
74 int l_new_image(lua_State
* L
)
78 if (lua_gettop(L
) > 0 && ! lua_istable(L
, -1)) {
79 luaL_error(L
, "img.new needs table as optional argument"); /* (t) */
81 aa
= (image
**) lua_newuserdata(L
, sizeof(image
*)); /* i (t) */
82 luaL_getmetatable(L
, TYPE_IMG
); /* m i (t) */
83 lua_setmetatable(L
, -2); /* i (t) */
84 a
= *aa
= new_image();
85 add
= (image_dict
**) lua_newuserdata(L
, sizeof(image_dict
*)); /* ad i (t) */
86 luaL_getmetatable(L
, TYPE_IMG_DICT
); /* m ad i (t) */
87 lua_setmetatable(L
, -2); /* ad i (t) */
88 img_dict(a
) = *add
= new_image_dict();
89 img_dictref(a
) = luaL_ref(L
, LUA_REGISTRYINDEX
); /* i (t) */
90 img_luaref(*add
) += 1;
91 if (lua_gettop(L
) == 2) { /* i t, else just i */
92 lua_insert(L
, -2); /* t i */
93 lua_pushnil(L
); /* n t i (1st key for iterator) */
94 while (lua_next(L
, -2) != 0) { /* v k t i */
95 lua_to_image(L
, a
, *add
); /* v k t i */
96 lua_pop(L
, 1); /* k t i */
98 lua_pop(L
, 1); /* i */
103 static int l_copy_image(lua_State
* L
)
105 if (lua_gettop(L
) != 1) {
106 luaL_error(L
, "img.copy needs an image as argument");
107 } else if (lua_istable(L
, 1)) {
108 (void) l_new_image(L
);
110 (void) copy_image(L
, 1.0);
115 static void read_scale_img(image
* a
)
119 luaL_error(Luas
, "the image scaler needs a valid image");
123 luaL_error(Luas
, "the image scaler needs a valid dictionary");
125 if (img_state(ad
) == DICT_NEW
) {
126 if (img_type(ad
) == IMG_TYPE_PDFSTREAM
)
127 check_pdfstream_dict(ad
);
132 if ((img_type(ad
) == IMG_TYPE_NONE
) || (img_state(ad
) == DICT_NEW
)) {
133 normal_warning("image","don't rely on the image data to be okay");
137 } else if (is_wd_running(a
) || is_ht_running(a
) || is_dp_running(a
)) {
138 img_dimen(a
) = scale_img(ad
, img_dimen(a
), img_transform(a
));
144 static int l_scan_image(lua_State
* L
)
147 if (lua_gettop(L
) != 1)
148 luaL_error(L
, "img.scan needs exactly 1 argument");
149 if (lua_istable(L
, 1))
150 (void) l_new_image(L
);
151 aa
= (image
**) luaL_checkudata(L
, 1, TYPE_IMG
);
153 check_o_mode(static_pdf
, "img.scan", 1 << OMODE_PDF
, false);
158 static halfword
img_to_node(lua_State
* L
, image
* a
)
163 luaL_error(L
, "img.tonode needs a valid image");
167 luaL_error(L
, "img.tonode image has no dictionary");
168 } else if (img_objnum(ad
) == 0) {
169 luaL_error(L
, "img.tonode got image without object number");
171 n
= new_rule(image_rule
);
172 rule_index(n
) = img_index(ad
);
173 width(n
) = img_width(a
);
174 height(n
) = img_height(a
);
175 depth(n
) = img_depth(a
);
176 rule_transform(n
) = img_transform(a
);
189 const char *wrtype_s
[] = {
191 "img.immediatewrite()",
196 static void setup_image(PDF pdf
, image
* a
, wrtype_e writetype
)
200 luaL_error(Luas
, "no valid image passed"); /* todo, also check in caller */
202 check_o_mode(pdf
, wrtype_s
[writetype
], 1 << OMODE_PDF
, false);
204 if (img_objnum(ad
) == 0) { /* latest needed just before out_img() */
206 img_objnum(ad
) = pdf_create_obj(pdf
, obj_type_ximage
, pdf
->ximage_count
);
207 img_index(ad
) = pdf
->ximage_count
;
208 idict_to_array(ad
); /* from now on ad is read-only */
209 obj_data_ptr(pdf
, pdf
->obj_ptr
) = img_index(ad
);
213 static void write_image_or_node(lua_State
* L
, wrtype_e writetype
)
218 if (lua_gettop(L
) != 1)
219 luaL_error(L
, "%s expects an argument", wrtype_s
[writetype
]);
220 if (lua_istable(L
, 1))
221 (void) l_new_image(L
);
222 aa
= (image
**) luaL_checkudata(L
, 1, TYPE_IMG
);
225 setup_image(static_pdf
, a
, writetype
);
228 n
= img_to_node(L
, a
);
231 case WR_IMMEDIATEWRITE
:
232 write_img(static_pdf
, ad
);
235 lua_pop(L
, 1); /* - */
236 n
= img_to_node(L
, a
);
237 lua_nodelib_push_fast(L
, n
);
240 luaL_error(L
, "%s expects an valid image", wrtype_s
[writetype
]);
242 if (img_state(ad
) < DICT_REFERED
)
243 img_state(ad
) = DICT_REFERED
;
246 static int l_write_image(lua_State
* L
)
248 write_image_or_node(L
, WR_WRITE
);
252 static int l_immediatewrite_image(lua_State
* L
)
254 check_o_mode(static_pdf
, "img.immediatewrite", 1 << OMODE_PDF
, true);
255 if (global_shipping_mode
!= NOT_SHIPPING
) {
256 luaL_error(L
, "img.immediatewrite can not be used with \\latelua");
258 write_image_or_node(L
, WR_IMMEDIATEWRITE
);
263 static int l_image_node(lua_State
* L
)
265 write_image_or_node(L
, WR_NODE
);
269 static int l_image_keys(lua_State
* L
)
271 return lua_show_valid_keys(L
, img_parms
, img_parms_max
);
274 static int l_image_types(lua_State
* L
)
276 return lua_show_valid_list(L
, img_types
, img_types_max
);
279 static int l_image_boxes(lua_State
* L
)
281 return lua_show_valid_keys(L
, img_pageboxes
, img_pageboxes_max
);
284 static const struct luaL_Reg imglib_f
[] = {
285 { "new", l_new_image
},
286 { "copy", l_copy_image
},
287 { "scan", l_scan_image
},
288 { "write", l_write_image
},
289 { "immediatewrite", l_immediatewrite_image
},
290 { "node", l_image_node
},
291 { "keys", l_image_keys
},
292 { "types", l_image_types
},
293 { "boxes", l_image_boxes
},
297 void vf_out_image(PDF pdf
, unsigned i
)
301 lua_rawgeti(Luas
, LUA_REGISTRYINDEX
, (int) i
);
302 aa
= (image
**) luaL_checkudata(Luas
, -1, TYPE_IMG
);
306 luaL_error(Luas
, "invalid image dictionary");
308 setup_image(pdf
, a
, WR_VF_IMG
);
309 place_img(pdf
, ad
, img_dimen(a
), img_transform(a
));
313 /* metamethods for image */
315 static int m_img_get(lua_State
* L
)
319 image
**a
= (image
**) luaL_checkudata(L
, 1, TYPE_IMG
); /* k u */
320 image_dict
*d
= img_dict(*a
);
322 luaL_error(L
, "invalid image dictionary");
324 s
= lua_tostring(L
, 2);
325 if (lua_key_eq(s
,width
)) {
326 if (is_wd_running(*a
)) {
329 lua_pushinteger(L
, img_width(*a
));
331 } else if (lua_key_eq(s
,height
)) {
332 if (is_ht_running(*a
)) {
335 lua_pushinteger(L
, img_height(*a
));
337 } else if (lua_key_eq(s
,depth
)) {
338 if (is_dp_running(*a
)) {
341 lua_pushinteger(L
, img_depth(*a
));
343 } else if (lua_key_eq(s
,transform
)) {
344 lua_pushinteger(L
, img_transform(*a
));
345 } else if (lua_key_eq(s
,filename
)) {
346 if (img_filename(d
) == NULL
|| strlen(img_filename(d
)) == 0) {
349 lua_pushstring(L
, img_filename(d
));
351 } else if (lua_key_eq(s
,visiblefilename
)) {
352 if (img_visiblefilename(d
) == NULL
|| strlen(img_visiblefilename(d
)) == 0) {
355 lua_pushstring(L
, img_visiblefilename(d
));
357 } else if (lua_key_eq(s
,keepopen
)) {
358 lua_pushboolean(L
, img_keepopen(d
));
359 } else if (lua_key_eq(s
,filepath
)) {
360 if (img_filepath(d
) == NULL
|| strlen(img_filepath(d
)) == 0) {
363 lua_pushstring(L
, img_filepath(d
));
365 } else if (lua_key_eq(s
,attr
)) {
366 if (img_attr(d
) == NULL
|| strlen(img_attr(d
)) == 0) {
369 lua_pushstring(L
, img_attr(d
));
371 } else if (lua_key_eq(s
,page
)) {
372 if (img_pagename(d
) != NULL
&& strlen(img_pagename(d
)) != 0) {
373 lua_pushstring(L
, img_pagename(d
));
375 lua_pushinteger(L
, img_pagenum(d
));
377 } else if (lua_key_eq(s
,pages
)) {
378 lua_pushinteger(L
, img_totalpages(d
));
379 } else if (lua_key_eq(s
,xsize
)) {
380 if ((img_rotation(d
) & 1) == 0) {
381 lua_pushinteger(L
, img_xsize(d
));
383 lua_pushinteger(L
, img_ysize(d
));
385 } else if (lua_key_eq(s
,ysize
)) {
386 if ((img_rotation(d
) & 1) == 0) {
387 lua_pushinteger(L
, img_ysize(d
));
389 lua_pushinteger(L
, img_xsize(d
));
391 } else if (lua_key_eq(s
,xres
)) {
392 lua_pushinteger(L
, img_xres(d
));
393 } else if (lua_key_eq(s
,yres
)) {
394 lua_pushinteger(L
, img_yres(d
));
395 } else if (lua_key_eq(s
,rotation
)) {
396 lua_pushinteger(L
, img_rotation(d
));
397 } else if (lua_key_eq(s
,orientation
)) {
398 lua_pushinteger(L
, img_orientation(d
));
399 } else if (lua_key_eq(s
,colorspace
)) {
400 if (img_colorspace(d
) == 0) {
403 lua_pushinteger(L
, img_colorspace(d
));
405 } else if (lua_key_eq(s
,colordepth
)) {
406 if (img_colordepth(d
) == 0) {
409 lua_pushinteger(L
, img_colordepth(d
));
411 } else if (lua_key_eq(s
,imagetype
)) {
413 if (j
>= 0 && j
<= img_types_max
) {
414 if (j
== IMG_TYPE_NONE
) {
417 lua_pushstring(L
, img_types
[j
]);
422 } else if (lua_key_eq(s
,pagebox
)) {
424 if (j
< 0 || j
>= img_pageboxes_max
) {
427 lua_push_img_pagebox(L
, j
);
428 } else if (lua_key_eq(s
,bbox
)) {
429 if (!img_is_bbox(d
)) {
430 img_bbox(d
)[0] = img_xorig(d
);
431 img_bbox(d
)[1] = img_yorig(d
);
432 img_bbox(d
)[2] = img_xorig(d
) + img_xsize(d
);
433 img_bbox(d
)[3] = img_yorig(d
) + img_ysize(d
);
436 lua_pushinteger(L
, 1);
437 lua_pushinteger(L
, img_bbox(d
)[0]);
439 lua_pushinteger(L
, 2);
440 lua_pushinteger(L
, img_bbox(d
)[1]);
442 lua_pushinteger(L
, 3);
443 lua_pushinteger(L
, img_bbox(d
)[2]);
445 lua_pushinteger(L
, 4);
446 lua_pushinteger(L
, img_bbox(d
)[3]);
448 } else if (lua_key_eq(s
,objnum
)) {
449 if (img_objnum(d
) == 0) {
452 lua_pushinteger(L
, img_objnum(d
));
454 } else if (lua_key_eq(s
,index
)) {
455 if (img_index(d
) == 0) {
458 lua_pushinteger(L
, img_index(d
));
460 } else if (lua_key_eq(s
,stream
)) {
461 if (img_type(d
) != IMG_TYPE_PDFSTREAM
462 || img_pdfstream_ptr(d
) == NULL
463 || img_pdfstream_stream(d
) == NULL
464 || strlen(img_pdfstream_stream(d
)) == 0) {
467 lua_pushstring(L
, img_pdfstream_stream(d
));
469 } else if (lua_key_eq(s
,ref_count
)) {
470 lua_pushinteger(L
, img_luaref(d
));
477 static void lua_to_image(lua_State
* L
, image
* a
, image_dict
* d
)
481 s
= lua_tostring(L
,-2);
483 if (lua_key_eq(s
,width
)) {
486 } else if (t
== LUA_TNUMBER
) {
487 img_width(a
) = (int) lua_roundnumber(L
, -1);
488 } else if (t
== LUA_TSTRING
) {
489 img_width(a
) = dimen_to_number(L
, lua_tostring(L
, -1));
491 luaL_error(L
, "image.width needs integer or nil value or dimension string");
493 } else if (lua_key_eq(s
,height
)) {
496 } else if (t
== LUA_TNUMBER
) {
497 img_height(a
) = (int) lua_roundnumber(L
, -1);
498 } else if (t
== LUA_TSTRING
) {
499 img_height(a
) = dimen_to_number(L
, lua_tostring(L
, -1));
501 luaL_error(L
, "image.height needs integer or nil value or dimension string");
503 } else if (lua_key_eq(s
,depth
)) {
506 } else if (t
== LUA_TNUMBER
) {
507 img_depth(a
) = (int) lua_roundnumber(L
, -1);
508 } else if (t
== LUA_TSTRING
) {
509 img_depth(a
) = dimen_to_number(L
, lua_tostring(L
, -1));
511 luaL_error(L
, "image.depth needs integer or nil value or dimension string");
513 } else if (lua_key_eq(s
,transform
)) {
514 if (t
== LUA_TNUMBER
) {
515 img_transform(a
) = (int) lua_tointeger(L
, -1);
517 luaL_error(L
, "image.transform needs integer value");
519 } else if (lua_key_eq(s
,filename
)) {
520 if (img_state(d
) >= DICT_FILESCANNED
) {
521 luaL_error(L
, "image.filename is now read-only");
522 } else if (img_type(d
) == IMG_TYPE_PDFSTREAM
) {
523 luaL_error(L
, "image.filename can't be used with image.stream");
524 } else if (t
== LUA_TSTRING
) {
525 xfree(img_filename(d
));
526 img_filename(d
) = xstrdup(lua_tostring(L
, -1));
528 luaL_error(L
, "image.filename needs string value");
530 } else if (lua_key_eq(s
,visiblefilename
)) {
531 if (img_state(d
) >= DICT_FILESCANNED
) {
532 luaL_error(L
, "image.visiblefilename is now read-only");
533 } else if (img_type(d
) == IMG_TYPE_PDFSTREAM
) {
534 luaL_error(L
, "image.visiblefilename can't be used with image.stream");
535 } else if (t
== LUA_TSTRING
) {
536 xfree(img_visiblefilename(d
));
537 img_visiblefilename(d
) = xstrdup(lua_tostring(L
, -1));
539 luaL_error(L
, "image.visiblefilename needs string value");
541 } else if (lua_key_eq(s
,attr
)) {
542 if (img_state(d
) >= DICT_FILESCANNED
) {
543 luaL_error(L
, "image.attr is now read-only");
544 } else if (t
== LUA_TSTRING
) {
546 img_attr(d
) = xstrdup(lua_tostring(L
, -1));
547 } else if (t
== LUA_TNIL
) {
550 luaL_error(L
, "image.attr needs string or nil value");
552 } else if (lua_key_eq(s
,page
)) {
553 if (img_state(d
) >= DICT_FILESCANNED
) {
554 luaL_error(L
, "image.page is now read-only");
555 } else if (t
== LUA_TSTRING
) {
556 xfree(img_pagename(d
));
557 img_pagename(d
) = xstrdup(lua_tostring(L
, -1));
559 } else if (t
== LUA_TNUMBER
) {
560 img_pagenum(d
) = (int) lua_tointeger(L
, -1);
561 xfree(img_pagename(d
));
563 luaL_error(L
, "image.page needs integer or string value");
565 } else if (lua_key_eq(s
,colorspace
)) {
566 if (img_state(d
) >= DICT_FILESCANNED
) {
567 luaL_error(L
, "image.colorspace is now read-only");
568 } else if (t
== LUA_TNIL
) {
569 img_colorspace(d
) = 0;
570 } else if (t
== LUA_TNUMBER
) {
571 img_colorspace(d
) = (int) lua_tointeger(L
, -1);
573 luaL_error(L
, "image.colorspace needs integer or nil value");
575 } else if (lua_key_eq(s
,pagebox
)) {
576 if (img_state(d
) >= DICT_FILESCANNED
) {
577 luaL_error(L
, "image.pagebox is now read-only");
578 } else if (t
== LUA_TNIL
) {
579 img_pagebox(d
) = PDF_BOX_SPEC_MEDIA
;
580 } else if (t
== LUA_TNUMBER
) {
581 i
= lua_tointeger(L
,-1);
582 if (i
< 0 || i
>= img_pageboxes_max
) {
583 img_pagebox(d
) = PDF_BOX_SPEC_MEDIA
;
587 } else if (t
== LUA_TSTRING
) {
588 img_pagebox(d
) = PDF_BOX_SPEC_MEDIA
;
589 for (i
= 0; i
< img_pageboxes_max
; i
++) {
590 lua_rawgeti(L
, LUA_REGISTRYINDEX
, img_pageboxes
[i
]);
591 if (lua_rawequal(L
,-1,-2)) {
600 luaL_error(L
, "image.pagebox needs string, number or nil value");
602 } else if (lua_key_eq(s
,keepopen
)) {
603 if (img_state(d
) >= DICT_FILESCANNED
) {
604 luaL_error(L
, "image.keepopen is now read-only");
605 } else if (t
!= LUA_TBOOLEAN
) {
606 luaL_error(L
, "image.bbox needs boolean value");
608 img_keepopen(d
) = lua_toboolean(L
, -1);
610 } else if (lua_key_eq(s
,bbox
)) {
611 if (img_state(d
) >= DICT_FILESCANNED
) {
612 luaL_error(L
, "image.bbox is now read-only");
613 } else if (t
!= LUA_TTABLE
) {
614 luaL_error(L
, "image.bbox needs table value");
615 } else if (lua_rawlen(L
, -1) != 4) {
616 luaL_error(L
, "image.bbox table must have exactly 4 elements");
618 for (i
= 1; i
<= 4; i
++) { /* v k t ... */
619 lua_pushinteger(L
, i
); /* idx v k t ... */
620 lua_gettable(L
, -2); /* int v k t ... */
622 if (t
== LUA_TNUMBER
) {
623 img_bbox(d
)[i
- 1] = (int) lua_roundnumber(L
, -1);
624 } else if (t
== LUA_TSTRING
) {
625 img_bbox(d
)[i
- 1] = dimen_to_number(L
, lua_tostring(L
, -1));
627 luaL_error(L
, "image.bbox table needs integer value or dimension string elements");
629 lua_pop(L
, 1); /* v k t ... */
633 } else if (lua_key_eq(s
,stream
)) {
634 if (img_filename(d
) != NULL
) {
635 luaL_error(L
, "image.stream can't be used with image.filename");
636 } else if (img_state(d
) >= DICT_FILESCANNED
) {
637 luaL_error(L
, "image.stream is now read-only");
639 if (img_pdfstream_ptr(d
) == NULL
) {
640 new_img_pdfstream_struct(d
);
642 xfree(img_pdfstream_stream(d
));
643 img_pdfstream_stream(d
) = xstrdup(lua_tostring(L
, -1));
644 img_type(d
) = IMG_TYPE_PDFSTREAM
;
647 luaL_error(L
, "image.%s can not be set", s
);
651 static int m_img_set(lua_State
* L
)
653 image
**a
= (image
**) luaL_checkudata(L
, 1, TYPE_IMG
); /* v k u */
654 image_dict
*d
= img_dict(*a
);
656 luaL_error(L
, "invalid image dictionary");
658 lua_to_image(L
, *a
, d
);
663 static int m_img_mul(lua_State
* L
)
666 if (lua_type(L
, 1) == LUA_TNUMBER
) { /* u? n */
667 (void) luaL_checkudata(L
, 2, TYPE_IMG
); /* u n */
668 lua_insert(L
, -2); /* n a */
669 } else if (lua_type(L
, 2) != LUA_TNUMBER
) { /* n u? */
670 (void) luaL_checkudata(L
, 1, TYPE_IMG
); /* n a */
672 scale
= lua_tonumber(L
, 2); /* float */ /* n a */
673 lua_pop(L
, 1); /* a */
674 copy_image(L
, scale
); /* b */
678 static int m_img_print(lua_State
* L
)
682 aa
= (image
**) luaL_checkudata(L
, 1, TYPE_IMG
);
684 /* formatted a bit like a node */
685 if (img_filename(d
) == NULL
) {
686 if (img_pagename(d
) != NULL
&& strlen(img_pagename(d
)) != 0) {
687 lua_pushfstring(L
, "<img unset : %d >", img_dictref(*aa
));
689 lua_pushfstring(L
, "<img unset : %d >", img_dictref(*aa
));
692 if (img_pagename(d
) != NULL
&& strlen(img_pagename(d
)) != 0) {
693 lua_pushfstring(L
, "<img %s : %s : %d >", img_filename(d
), img_pagename(d
), img_dictref(*aa
));
695 lua_pushfstring(L
, "<img %s : %d : %d >", img_filename(d
), img_pagenum(d
), img_dictref(*aa
));
701 /* this finalizes instance */
703 static int m_img_gc(lua_State
* L
)
707 aa
= (image
**) luaL_checkudata(L
, 1, TYPE_IMG
);
710 luaL_unref(L
, LUA_REGISTRYINDEX
, img_dictref(a
));
712 /* we need to check this */
713 if (!img_is_refered(d
)) {
722 static const struct luaL_Reg img_m
[] = {
723 {"__index", m_img_get
},
724 {"__newindex", m_img_set
},
725 {"__mul", m_img_mul
},
726 {"__tostring", m_img_print
},
731 /* this finalizes the dict */
733 static int m_img_dict_gc(lua_State
* L
)
735 image_dict
*ad
, **add
;
736 add
= (image_dict
**) luaL_checkudata(L
, 1, TYPE_IMG_DICT
);
738 if (img_luaref(ad
) > 0) {
739 luaL_error(L
, "disposing image dict that has references");
741 /* we need to check this */
742 if (img_state(ad
) < DICT_REFERED
) {
750 /* the (shared) dict */
752 static const struct luaL_Reg img_dict_m
[] = {
753 {"__gc", m_img_dict_gc
},
757 int luaopen_img(lua_State
* L
)
759 luaL_newmetatable(L
, TYPE_IMG
);
761 luaL_register(L
, NULL
, img_m
);
762 luaL_newmetatable(L
, TYPE_IMG_DICT
);
763 luaL_register(L
, NULL
, img_dict_m
);
764 luaL_register(L
, "img", imglib_f
);
766 luaL_setfuncs(L
, img_m
, 0);
767 luaL_newmetatable(L
, TYPE_IMG_DICT
);
768 luaL_setfuncs(L
, img_dict_m
, 0);
769 luaL_newlib(L
, imglib_f
);