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
)
302 lua_rawgeti(L
, LUA_REGISTRYINDEX
, (int) i
);
303 aa
= (image
**) luaL_checkudata(L
, -1, TYPE_IMG
);
307 luaL_error(L
, "invalid image dictionary");
309 setup_image(pdf
, a
, WR_VF_IMG
);
310 place_img(pdf
, ad
, img_dimen(a
), img_transform(a
));
314 /* metamethods for image */
316 static int m_img_get(lua_State
* L
)
320 image
**a
= (image
**) luaL_checkudata(L
, 1, TYPE_IMG
); /* k u */
321 image_dict
*d
= img_dict(*a
);
323 luaL_error(L
, "invalid image dictionary");
325 s
= lua_tostring(L
, 2);
326 if (lua_key_eq(s
,width
)) {
327 if (is_wd_running(*a
)) {
330 lua_pushinteger(L
, img_width(*a
));
332 } else if (lua_key_eq(s
,height
)) {
333 if (is_ht_running(*a
)) {
336 lua_pushinteger(L
, img_height(*a
));
338 } else if (lua_key_eq(s
,depth
)) {
339 if (is_dp_running(*a
)) {
342 lua_pushinteger(L
, img_depth(*a
));
344 } else if (lua_key_eq(s
,transform
)) {
345 lua_pushinteger(L
, img_transform(*a
));
346 } else if (lua_key_eq(s
,filename
)) {
347 if (img_filename(d
) == NULL
|| strlen(img_filename(d
)) == 0) {
350 lua_pushstring(L
, img_filename(d
));
352 } else if (lua_key_eq(s
,visiblefilename
)) {
353 if (img_visiblefilename(d
) == NULL
|| strlen(img_visiblefilename(d
)) == 0) {
356 lua_pushstring(L
, img_visiblefilename(d
));
358 } else if (lua_key_eq(s
,keepopen
)) {
359 lua_pushboolean(L
, img_keepopen(d
));
360 } else if (lua_key_eq(s
,filepath
)) {
361 if (img_filepath(d
) == NULL
|| strlen(img_filepath(d
)) == 0) {
364 lua_pushstring(L
, img_filepath(d
));
366 } else if (lua_key_eq(s
,attr
)) {
367 if (img_attr(d
) == NULL
|| strlen(img_attr(d
)) == 0) {
370 lua_pushstring(L
, img_attr(d
));
372 } else if (lua_key_eq(s
,page
)) {
373 if (img_pagename(d
) != NULL
&& strlen(img_pagename(d
)) != 0) {
374 lua_pushstring(L
, img_pagename(d
));
376 lua_pushinteger(L
, img_pagenum(d
));
378 } else if (lua_key_eq(s
,pages
)) {
379 lua_pushinteger(L
, img_totalpages(d
));
380 } else if (lua_key_eq(s
,xsize
)) {
381 if ((img_rotation(d
) & 1) == 0) {
382 lua_pushinteger(L
, img_xsize(d
));
384 lua_pushinteger(L
, img_ysize(d
));
386 } else if (lua_key_eq(s
,ysize
)) {
387 if ((img_rotation(d
) & 1) == 0) {
388 lua_pushinteger(L
, img_ysize(d
));
390 lua_pushinteger(L
, img_xsize(d
));
392 } else if (lua_key_eq(s
,xres
)) {
393 lua_pushinteger(L
, img_xres(d
));
394 } else if (lua_key_eq(s
,yres
)) {
395 lua_pushinteger(L
, img_yres(d
));
396 } else if (lua_key_eq(s
,rotation
)) {
397 lua_pushinteger(L
, img_rotation(d
));
398 } else if (lua_key_eq(s
,colorspace
)) {
399 if (img_colorspace(d
) == 0) {
402 lua_pushinteger(L
, img_colorspace(d
));
404 } else if (lua_key_eq(s
,colordepth
)) {
405 if (img_colordepth(d
) == 0) {
408 lua_pushinteger(L
, img_colordepth(d
));
410 } else if (lua_key_eq(s
,imagetype
)) {
412 if (j
>= 0 && j
<= img_types_max
) {
413 if (j
== IMG_TYPE_NONE
) {
416 lua_pushstring(L
, img_types
[j
]);
421 } else if (lua_key_eq(s
,pagebox
)) {
423 if (j
< 0 || j
>= img_pageboxes_max
) {
426 lua_push_img_pagebox(L
, j
);
427 } else if (lua_key_eq(s
,bbox
)) {
428 if (!img_is_bbox(d
)) {
429 img_bbox(d
)[0] = img_xorig(d
);
430 img_bbox(d
)[1] = img_yorig(d
);
431 img_bbox(d
)[2] = img_xorig(d
) + img_xsize(d
);
432 img_bbox(d
)[3] = img_yorig(d
) + img_ysize(d
);
435 lua_pushinteger(L
, 1);
436 lua_pushinteger(L
, img_bbox(d
)[0]);
438 lua_pushinteger(L
, 2);
439 lua_pushinteger(L
, img_bbox(d
)[1]);
441 lua_pushinteger(L
, 3);
442 lua_pushinteger(L
, img_bbox(d
)[2]);
444 lua_pushinteger(L
, 4);
445 lua_pushinteger(L
, img_bbox(d
)[3]);
447 } else if (lua_key_eq(s
,objnum
)) {
448 if (img_objnum(d
) == 0) {
451 lua_pushinteger(L
, img_objnum(d
));
453 } else if (lua_key_eq(s
,index
)) {
454 if (img_index(d
) == 0) {
457 lua_pushinteger(L
, img_index(d
));
459 } else if (lua_key_eq(s
,stream
)) {
460 if (img_type(d
) != IMG_TYPE_PDFSTREAM
461 || img_pdfstream_ptr(d
) == NULL
462 || img_pdfstream_stream(d
) == NULL
463 || strlen(img_pdfstream_stream(d
)) == 0) {
466 lua_pushstring(L
, img_pdfstream_stream(d
));
468 } else if (lua_key_eq(s
,ref_count
)) {
469 lua_pushinteger(L
, img_luaref(d
));
476 static void lua_to_image(lua_State
* L
, image
* a
, image_dict
* d
)
480 s
= lua_tostring(L
,-2);
482 if (lua_key_eq(s
,width
)) {
485 } else if (t
== LUA_TNUMBER
) {
486 img_width(a
) = (int) lua_tointeger(L
, -1);
487 } else if (t
== LUA_TSTRING
) {
488 img_width(a
) = dimen_to_number(L
, lua_tostring(L
, -1));
490 luaL_error(L
, "image.width needs integer or nil value or dimension string");
492 } else if (lua_key_eq(s
,height
)) {
495 } else if (t
== LUA_TNUMBER
) {
496 img_height(a
) = (int) lua_tointeger(L
, -1);
497 } else if (t
== LUA_TSTRING
) {
498 img_height(a
) = dimen_to_number(L
, lua_tostring(L
, -1));
500 luaL_error(L
, "image.height needs integer or nil value or dimension string");
502 } else if (lua_key_eq(s
,depth
)) {
505 } else if (t
== LUA_TNUMBER
) {
506 img_depth(a
) = (int) lua_tointeger(L
, -1);
507 } else if (t
== LUA_TSTRING
) {
508 img_depth(a
) = dimen_to_number(L
, lua_tostring(L
, -1));
510 luaL_error(L
, "image.depth needs integer or nil value or dimension string");
512 } else if (lua_key_eq(s
,transform
)) {
513 if (t
== LUA_TNUMBER
) {
514 img_transform(a
) = (int) lua_tointeger(L
, -1);
516 luaL_error(L
, "image.transform needs integer value");
518 } else if (lua_key_eq(s
,filename
)) {
519 if (img_state(d
) >= DICT_FILESCANNED
) {
520 luaL_error(L
, "image.filename is now read-only");
521 } else if (img_type(d
) == IMG_TYPE_PDFSTREAM
) {
522 luaL_error(L
, "image.filename can't be used with image.stream");
523 } else if (t
== LUA_TSTRING
) {
524 xfree(img_filename(d
));
525 img_filename(d
) = xstrdup(lua_tostring(L
, -1));
527 luaL_error(L
, "image.filename needs string value");
529 } else if (lua_key_eq(s
,visiblefilename
)) {
530 if (img_state(d
) >= DICT_FILESCANNED
) {
531 luaL_error(L
, "image.visiblefilename is now read-only");
532 } else if (img_type(d
) == IMG_TYPE_PDFSTREAM
) {
533 luaL_error(L
, "image.visiblefilename can't be used with image.stream");
534 } else if (t
== LUA_TSTRING
) {
535 xfree(img_visiblefilename(d
));
536 img_visiblefilename(d
) = xstrdup(lua_tostring(L
, -1));
538 luaL_error(L
, "image.visiblefilename needs string value");
540 } else if (lua_key_eq(s
,attr
)) {
541 if (img_state(d
) >= DICT_FILESCANNED
) {
542 luaL_error(L
, "image.attr is now read-only");
543 } else if (t
== LUA_TSTRING
) {
545 img_attr(d
) = xstrdup(lua_tostring(L
, -1));
546 } else if (t
== LUA_TNIL
) {
549 luaL_error(L
, "image.attr needs string or nil value");
551 } else if (lua_key_eq(s
,page
)) {
552 if (img_state(d
) >= DICT_FILESCANNED
) {
553 luaL_error(L
, "image.page is now read-only");
554 } else if (t
== LUA_TSTRING
) {
555 xfree(img_pagename(d
));
556 img_pagename(d
) = xstrdup(lua_tostring(L
, -1));
558 } else if (t
== LUA_TNUMBER
) {
559 img_pagenum(d
) = (int) lua_tointeger(L
, -1);
560 xfree(img_pagename(d
));
562 luaL_error(L
, "image.page needs integer or string value");
564 } else if (lua_key_eq(s
,colorspace
)) {
565 if (img_state(d
) >= DICT_FILESCANNED
) {
566 luaL_error(L
, "image.colorspace is now read-only");
567 } else if (t
== LUA_TNIL
) {
568 img_colorspace(d
) = 0;
569 } else if (t
== LUA_TNUMBER
) {
570 img_colorspace(d
) = (int) lua_tointeger(L
, -1);
572 luaL_error(L
, "image.colorspace needs integer or nil value");
574 } else if (lua_key_eq(s
,pagebox
)) {
575 if (img_state(d
) >= DICT_FILESCANNED
) {
576 luaL_error(L
, "image.pagebox is now read-only");
577 } else if (t
== LUA_TNIL
) {
578 img_pagebox(d
) = PDF_BOX_SPEC_MEDIA
;
579 } else if (t
== LUA_TNUMBER
) {
580 i
= lua_tointeger(L
,-1);
581 if (i
< 0 || i
>= img_pageboxes_max
) {
582 img_pagebox(d
) = PDF_BOX_SPEC_MEDIA
;
586 } else if (t
== LUA_TSTRING
) {
587 img_pagebox(d
) = PDF_BOX_SPEC_MEDIA
;
588 for (i
= 0; i
< img_pageboxes_max
; i
++) {
589 lua_rawgeti(L
, LUA_REGISTRYINDEX
, img_pageboxes
[i
]);
590 if (lua_rawequal(L
,-1,-2)) {
599 luaL_error(L
, "image.pagebox needs string, number or nil value");
601 } else if (lua_key_eq(s
,keepopen
)) {
602 if (img_state(d
) >= DICT_FILESCANNED
) {
603 luaL_error(L
, "image.keepopen is now read-only");
604 } else if (t
!= LUA_TBOOLEAN
) {
605 luaL_error(L
, "image.bbox needs boolean value");
607 img_keepopen(d
) = lua_toboolean(L
, -1);
609 } else if (lua_key_eq(s
,bbox
)) {
610 if (img_state(d
) >= DICT_FILESCANNED
) {
611 luaL_error(L
, "image.bbox is now read-only");
612 } else if (t
!= LUA_TTABLE
) {
613 luaL_error(L
, "image.bbox needs table value");
614 } else if (lua_rawlen(L
, -1) != 4) {
615 luaL_error(L
, "image.bbox table must have exactly 4 elements");
617 for (i
= 1; i
<= 4; i
++) { /* v k t ... */
618 lua_pushinteger(L
, i
); /* idx v k t ... */
619 lua_gettable(L
, -2); /* int v k t ... */
621 if (t
== LUA_TNUMBER
) {
622 img_bbox(d
)[i
- 1] = (int) lua_tointeger(L
, -1);
623 } else if (t
== LUA_TSTRING
) {
624 img_bbox(d
)[i
- 1] = dimen_to_number(L
, lua_tostring(L
, -1));
626 luaL_error(L
, "image.bbox table needs integer value or dimension string elements");
628 lua_pop(L
, 1); /* v k t ... */
632 } else if (lua_key_eq(s
,stream
)) {
633 if (img_filename(d
) != NULL
) {
634 luaL_error(L
, "image.stream can't be used with image.filename");
635 } else if (img_state(d
) >= DICT_FILESCANNED
) {
636 luaL_error(L
, "image.stream is now read-only");
638 if (img_pdfstream_ptr(d
) == NULL
) {
639 new_img_pdfstream_struct(d
);
641 xfree(img_pdfstream_stream(d
));
642 img_pdfstream_stream(d
) = xstrdup(lua_tostring(L
, -1));
643 img_type(d
) = IMG_TYPE_PDFSTREAM
;
646 luaL_error(L
, "image.%s can not be set", s
);
650 static int m_img_set(lua_State
* L
)
652 image
**a
= (image
**) luaL_checkudata(L
, 1, TYPE_IMG
); /* v k u */
653 image_dict
*d
= img_dict(*a
);
655 luaL_error(L
, "invalid image dictionary");
657 lua_to_image(L
, *a
, d
);
662 static int m_img_mul(lua_State
* L
)
665 if (lua_type(L
, 1) == LUA_TNUMBER
) { /* u? n */
666 (void) luaL_checkudata(L
, 2, TYPE_IMG
); /* u n */
667 lua_insert(L
, -2); /* n a */
668 } else if (lua_type(L
, 2) != LUA_TNUMBER
) { /* n u? */
669 (void) luaL_checkudata(L
, 1, TYPE_IMG
); /* n a */
671 scale
= lua_tonumber(L
, 2); /* float */ /* n a */
672 lua_pop(L
, 1); /* a */
673 copy_image(L
, scale
); /* b */
677 static int m_img_print(lua_State
* L
)
681 aa
= (image
**) luaL_checkudata(L
, 1, TYPE_IMG
);
683 /* formatted a bit like a node */
684 if (img_filename(d
) == NULL
) {
685 if (img_pagename(d
) != NULL
&& strlen(img_pagename(d
)) != 0) {
686 lua_pushfstring(L
, "<img unset : %d >", img_dictref(*aa
));
688 lua_pushfstring(L
, "<img unset : %d >", img_dictref(*aa
));
691 if (img_pagename(d
) != NULL
&& strlen(img_pagename(d
)) != 0) {
692 lua_pushfstring(L
, "<img %s : %s : %d >", img_filename(d
), img_pagename(d
), img_dictref(*aa
));
694 lua_pushfstring(L
, "<img %s : %d : %d >", img_filename(d
), img_pagenum(d
), img_dictref(*aa
));
700 /* this finalizes instance */
702 static int m_img_gc(lua_State
* L
)
706 aa
= (image
**) luaL_checkudata(L
, 1, TYPE_IMG
);
709 luaL_unref(L
, LUA_REGISTRYINDEX
, img_dictref(a
));
711 /* we need to check this */
712 if (!img_is_refered(d
)) {
721 static const struct luaL_Reg img_m
[] = {
722 {"__index", m_img_get
},
723 {"__newindex", m_img_set
},
724 {"__mul", m_img_mul
},
725 {"__tostring", m_img_print
},
730 /* this finalizes the dict */
732 static int m_img_dict_gc(lua_State
* L
)
734 image_dict
*ad
, **add
;
735 add
= (image_dict
**) luaL_checkudata(L
, 1, TYPE_IMG_DICT
);
737 if (img_luaref(ad
) > 0) {
738 luaL_error(L
, "disposing image dict that has references");
740 /* we need to check this */
741 if (img_state(ad
) < DICT_REFERED
) {
749 /* the (shared) dict */
751 static const struct luaL_Reg img_dict_m
[] = {
752 {"__gc", m_img_dict_gc
},
756 int luaopen_img(lua_State
* L
)
758 luaL_newmetatable(L
, TYPE_IMG
);
760 luaL_register(L
, NULL
, img_m
);
761 luaL_newmetatable(L
, TYPE_IMG_DICT
);
762 luaL_register(L
, NULL
, img_dict_m
);
763 luaL_register(L
, "img", imglib_f
);
765 luaL_setfuncs(L
, img_m
, 0);
766 luaL_newmetatable(L
, TYPE_IMG_DICT
);
767 luaL_setfuncs(L
, img_dict_m
, 0);
768 luaL_newlib(L
, imglib_f
);