jas_image.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. /*
  2. * Copyright (c) 1999-2000 Image Power, Inc. and the University of
  3. * British Columbia.
  4. * Copyright (c) 2001-2003 Michael David Adams.
  5. * All rights reserved.
  6. */
  7. /* __START_OF_JASPER_LICENSE__
  8. *
  9. * JasPer License Version 2.0
  10. *
  11. * Copyright (c) 2001-2006 Michael David Adams
  12. * Copyright (c) 1999-2000 Image Power, Inc.
  13. * Copyright (c) 1999-2000 The University of British Columbia
  14. *
  15. * All rights reserved.
  16. *
  17. * Permission is hereby granted, free of charge, to any person (the
  18. * "User") obtaining a copy of this software and associated documentation
  19. * files (the "Software"), to deal in the Software without restriction,
  20. * including without limitation the rights to use, copy, modify, merge,
  21. * publish, distribute, and/or sell copies of the Software, and to permit
  22. * persons to whom the Software is furnished to do so, subject to the
  23. * following conditions:
  24. *
  25. * 1. The above copyright notices and this permission notice (which
  26. * includes the disclaimer below) shall be included in all copies or
  27. * substantial portions of the Software.
  28. *
  29. * 2. The name of a copyright holder shall not be used to endorse or
  30. * promote products derived from the Software without specific prior
  31. * written permission.
  32. *
  33. * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
  34. * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
  35. * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
  36. * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
  37. * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  38. * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
  39. * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
  40. * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
  41. * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  42. * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  43. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
  44. * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
  45. * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
  46. * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
  47. * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
  48. * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
  49. * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
  50. * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
  51. * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
  52. * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
  53. * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
  54. * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
  55. * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
  56. * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
  57. * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
  58. * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
  59. *
  60. * __END_OF_JASPER_LICENSE__
  61. */
  62. /*
  63. * Image Class
  64. *
  65. * $Id: jas_image.h,v 1.2 2008-05-26 09:41:51 vp153 Exp $
  66. */
  67. #ifndef JAS_IMAGE_H
  68. #define JAS_IMAGE_H
  69. /******************************************************************************\
  70. * Includes.
  71. \******************************************************************************/
  72. #include <jasper/jas_config.h>
  73. #include <jasper/jas_stream.h>
  74. #include <jasper/jas_seq.h>
  75. #include <jasper/jas_cm.h>
  76. #include <stdio.h>
  77. #ifdef __cplusplus
  78. extern "C" {
  79. #endif
  80. /******************************************************************************\
  81. * Constants.
  82. \******************************************************************************/
  83. /*
  84. * Miscellaneous constants.
  85. */
  86. /* The threshold at which image data is no longer stored in memory. */
  87. #define JAS_IMAGE_INMEMTHRESH (16 * 1024 * 1024)
  88. /*
  89. * Component types
  90. */
  91. #define JAS_IMAGE_CT_UNKNOWN 0x10000
  92. #define JAS_IMAGE_CT_COLOR(n) ((n) & 0x7fff)
  93. #define JAS_IMAGE_CT_OPACITY 0x08000
  94. #define JAS_IMAGE_CT_RGB_R 0
  95. #define JAS_IMAGE_CT_RGB_G 1
  96. #define JAS_IMAGE_CT_RGB_B 2
  97. #define JAS_IMAGE_CT_YCBCR_Y 0
  98. #define JAS_IMAGE_CT_YCBCR_CB 1
  99. #define JAS_IMAGE_CT_YCBCR_CR 2
  100. #define JAS_IMAGE_CT_GRAY_Y 0
  101. /******************************************************************************\
  102. * Simple types.
  103. \******************************************************************************/
  104. /* Image coordinate. */
  105. typedef int_fast32_t jas_image_coord_t;
  106. /* Color space (e.g., RGB, YCbCr). */
  107. typedef int_fast16_t jas_image_colorspc_t;
  108. /* Component type (e.g., color, opacity). */
  109. typedef int_fast32_t jas_image_cmpttype_t;
  110. /* Component sample data format (e.g., real/integer, signedness, precision). */
  111. typedef int_fast16_t jas_image_smpltype_t;
  112. /******************************************************************************\
  113. * Image class and supporting classes.
  114. \******************************************************************************/
  115. /* Image component class. */
  116. typedef struct {
  117. jas_image_coord_t tlx_;
  118. /* The x-coordinate of the top-left corner of the component. */
  119. jas_image_coord_t tly_;
  120. /* The y-coordinate of the top-left corner of the component. */
  121. jas_image_coord_t hstep_;
  122. /* The horizontal sampling period in units of the reference grid. */
  123. jas_image_coord_t vstep_;
  124. /* The vertical sampling period in units of the reference grid. */
  125. jas_image_coord_t width_;
  126. /* The component width in samples. */
  127. jas_image_coord_t height_;
  128. /* The component height in samples. */
  129. #ifdef FIX_ME
  130. int smpltype_;
  131. #else
  132. int prec_;
  133. /* The precision of the sample data (i.e., the number of bits per
  134. sample). If the samples are signed values, this quantity
  135. includes the sign bit. */
  136. int sgnd_;
  137. /* The signedness of the sample data. */
  138. #endif
  139. jas_stream_t *stream_;
  140. /* The stream containing the component data. */
  141. int cps_;
  142. /* The number of characters per sample in the stream. */
  143. jas_image_cmpttype_t type_;
  144. /* The type of component (e.g., opacity, red, green, blue, luma). */
  145. } jas_image_cmpt_t;
  146. /* Image class. */
  147. typedef struct {
  148. jas_image_coord_t tlx_;
  149. /* The x-coordinate of the top-left corner of the image bounding box. */
  150. jas_image_coord_t tly_;
  151. /* The y-coordinate of the top-left corner of the image bounding box. */
  152. jas_image_coord_t brx_;
  153. /* The x-coordinate of the bottom-right corner of the image bounding
  154. box (plus one). */
  155. jas_image_coord_t bry_;
  156. /* The y-coordinate of the bottom-right corner of the image bounding
  157. box (plus one). */
  158. int numcmpts_;
  159. /* The number of components. */
  160. int maxcmpts_;
  161. /* The maximum number of components that this image can have (i.e., the
  162. allocated size of the components array). */
  163. jas_image_cmpt_t **cmpts_;
  164. /* Per-component information. */
  165. jas_clrspc_t clrspc_;
  166. jas_cmprof_t *cmprof_;
  167. bool inmem_;
  168. } jas_image_t;
  169. /* Component parameters class. */
  170. /* This data type exists solely/mainly for the purposes of the
  171. jas_image_create function. */
  172. typedef struct {
  173. jas_image_coord_t tlx;
  174. /* The x-coordinate of the top-left corner of the component. */
  175. jas_image_coord_t tly;
  176. /* The y-coordinate of the top-left corner of the component. */
  177. jas_image_coord_t hstep;
  178. /* The horizontal sampling period in units of the reference grid. */
  179. jas_image_coord_t vstep;
  180. /* The vertical sampling period in units of the reference grid. */
  181. jas_image_coord_t width;
  182. /* The width of the component in samples. */
  183. jas_image_coord_t height;
  184. /* The height of the component in samples. */
  185. #ifdef FIX_ME
  186. int smpltype;
  187. #else
  188. int prec;
  189. /* The precision of the component sample data. */
  190. int sgnd;
  191. /* The signedness of the component sample data. */
  192. #endif
  193. } jas_image_cmptparm_t;
  194. /******************************************************************************\
  195. * File format related classes.
  196. \******************************************************************************/
  197. #define JAS_IMAGE_MAXFMTS 32
  198. /* The maximum number of image data formats supported. */
  199. /* Image format-dependent operations. */
  200. typedef struct {
  201. jas_image_t *(*decode)(jas_stream_t *in, char *opts);
  202. /* Decode image data from a stream. */
  203. int (*encode)(jas_image_t *image, jas_stream_t *out, char *opts);
  204. /* Encode image data to a stream. */
  205. int (*validate)(jas_stream_t *in);
  206. /* Determine if stream data is in a particular format. */
  207. } jas_image_fmtops_t;
  208. /* Image format information. */
  209. typedef struct {
  210. int id;
  211. /* The ID for this format. */
  212. char *name;
  213. /* The name by which this format is identified. */
  214. char *ext;
  215. /* The file name extension associated with this format. */
  216. char *desc;
  217. /* A brief description of the format. */
  218. jas_image_fmtops_t ops;
  219. /* The operations for this format. */
  220. } jas_image_fmtinfo_t;
  221. /******************************************************************************\
  222. * Image operations.
  223. \******************************************************************************/
  224. /* Create an image. */
  225. jas_image_t *jas_image_create(int numcmpts,
  226. jas_image_cmptparm_t *cmptparms, jas_clrspc_t clrspc);
  227. /* Create an "empty" image. */
  228. jas_image_t *jas_image_create0(void);
  229. /* Clone an image. */
  230. jas_image_t *jas_image_copy(jas_image_t *image);
  231. /* Deallocate any resources associated with an image. */
  232. void jas_image_destroy(jas_image_t *image);
  233. /* Get the width of the image in units of the image reference grid. */
  234. #define jas_image_width(image) \
  235. ((image)->brx_ - (image)->tlx_)
  236. /* Get the height of the image in units of the image reference grid. */
  237. #define jas_image_height(image) \
  238. ((image)->bry_ - (image)->tly_)
  239. /* Get the x-coordinate of the top-left corner of the image bounding box
  240. on the reference grid. */
  241. #define jas_image_tlx(image) \
  242. ((image)->tlx_)
  243. /* Get the y-coordinate of the top-left corner of the image bounding box
  244. on the reference grid. */
  245. #define jas_image_tly(image) \
  246. ((image)->tly_)
  247. /* Get the x-coordinate of the bottom-right corner of the image bounding box
  248. on the reference grid (plus one). */
  249. #define jas_image_brx(image) \
  250. ((image)->brx_)
  251. /* Get the y-coordinate of the bottom-right corner of the image bounding box
  252. on the reference grid (plus one). */
  253. #define jas_image_bry(image) \
  254. ((image)->bry_)
  255. /* Get the number of image components. */
  256. #define jas_image_numcmpts(image) \
  257. ((image)->numcmpts_)
  258. /* Get the color model used by the image. */
  259. #define jas_image_clrspc(image) \
  260. ((image)->clrspc_)
  261. /* Set the color model for an image. */
  262. #define jas_image_setclrspc(image, clrspc) \
  263. ((image)->clrspc_ = (clrspc))
  264. #define jas_image_cmpttype(image, cmptno) \
  265. ((image)->cmpts_[(cmptno)]->type_)
  266. #define jas_image_setcmpttype(image, cmptno, type) \
  267. ((image)->cmpts_[(cmptno)]->type_ = (type))
  268. /* Get the width of a component. */
  269. #define jas_image_cmptwidth(image, cmptno) \
  270. ((image)->cmpts_[cmptno]->width_)
  271. /* Get the height of a component. */
  272. #define jas_image_cmptheight(image, cmptno) \
  273. ((image)->cmpts_[cmptno]->height_)
  274. /* Get the signedness of the sample data for a component. */
  275. #define jas_image_cmptsgnd(image, cmptno) \
  276. ((image)->cmpts_[cmptno]->sgnd_)
  277. /* Get the precision of the sample data for a component. */
  278. #define jas_image_cmptprec(image, cmptno) \
  279. ((image)->cmpts_[cmptno]->prec_)
  280. /* Get the horizontal subsampling factor for a component. */
  281. #define jas_image_cmpthstep(image, cmptno) \
  282. ((image)->cmpts_[cmptno]->hstep_)
  283. /* Get the vertical subsampling factor for a component. */
  284. #define jas_image_cmptvstep(image, cmptno) \
  285. ((image)->cmpts_[cmptno]->vstep_)
  286. /* Get the x-coordinate of the top-left corner of a component. */
  287. #define jas_image_cmpttlx(image, cmptno) \
  288. ((image)->cmpts_[cmptno]->tlx_)
  289. /* Get the y-coordinate of the top-left corner of a component. */
  290. #define jas_image_cmpttly(image, cmptno) \
  291. ((image)->cmpts_[cmptno]->tly_)
  292. /* Get the x-coordinate of the bottom-right corner of a component
  293. (plus "one"). */
  294. #define jas_image_cmptbrx(image, cmptno) \
  295. ((image)->cmpts_[cmptno]->tlx_ + (image)->cmpts_[cmptno]->width_ * \
  296. (image)->cmpts_[cmptno]->hstep_)
  297. /* Get the y-coordinate of the bottom-right corner of a component
  298. (plus "one"). */
  299. #define jas_image_cmptbry(image, cmptno) \
  300. ((image)->cmpts_[cmptno]->tly_ + (image)->cmpts_[cmptno]->height_ * \
  301. (image)->cmpts_[cmptno]->vstep_)
  302. /* Get the raw size of an image (i.e., the nominal size of the image without
  303. any compression. */
  304. uint_fast32_t jas_image_rawsize(jas_image_t *image);
  305. /* Create an image from a stream in some specified format. */
  306. jas_image_t *jas_image_decode(jas_stream_t *in, int fmt, char *optstr);
  307. /* Write an image to a stream in a specified format. */
  308. int jas_image_encode(jas_image_t *image, jas_stream_t *out, int fmt,
  309. char *optstr);
  310. /* Read a rectangular region of an image component. */
  311. /* The position and size of the rectangular region to be read is specified
  312. relative to the component's coordinate system. */
  313. int jas_image_readcmpt(jas_image_t *image, int cmptno,
  314. jas_image_coord_t x, jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height,
  315. jas_matrix_t *data);
  316. /* Write a rectangular region of an image component. */
  317. int jas_image_writecmpt(jas_image_t *image, int cmptno,
  318. jas_image_coord_t x, jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height,
  319. jas_matrix_t *data);
  320. /* Delete a component from an image. */
  321. void jas_image_delcmpt(jas_image_t *image, int cmptno);
  322. /* Add a component to an image. */
  323. int jas_image_addcmpt(jas_image_t *image, int cmptno,
  324. jas_image_cmptparm_t *cmptparm);
  325. /* Copy a component from one image to another. */
  326. int jas_image_copycmpt(jas_image_t *dstimage, int dstcmptno,
  327. jas_image_t *srcimage, int srccmptno);
  328. #define JAS_IMAGE_CDT_GETSGND(dtype) (((dtype) >> 7) & 1)
  329. #define JAS_IMAGE_CDT_SETSGND(dtype) (((dtype) & 1) << 7)
  330. #define JAS_IMAGE_CDT_GETPREC(dtype) ((dtype) & 0x7f)
  331. #define JAS_IMAGE_CDT_SETPREC(dtype) ((dtype) & 0x7f)
  332. #define jas_image_cmptdtype(image, cmptno) \
  333. (JAS_IMAGE_CDT_SETSGND((image)->cmpts_[cmptno]->sgnd_) | JAS_IMAGE_CDT_SETPREC((image)->cmpts_[cmptno]->prec_))
  334. int jas_image_depalettize(jas_image_t *image, int cmptno, int numlutents,
  335. int_fast32_t *lutents, int dtype, int newcmptno);
  336. int jas_image_readcmptsample(jas_image_t *image, int cmptno, int x, int y);
  337. void jas_image_writecmptsample(jas_image_t *image, int cmptno, int x, int y,
  338. int_fast32_t v);
  339. int jas_image_getcmptbytype(jas_image_t *image, int ctype);
  340. /******************************************************************************\
  341. * Image format-related operations.
  342. \******************************************************************************/
  343. /* Clear the table of image formats. */
  344. void jas_image_clearfmts(void);
  345. /* Add entry to table of image formats. */
  346. int jas_image_addfmt(int id, char *name, char *ext, char *desc,
  347. jas_image_fmtops_t *ops);
  348. /* Get the ID for the image format with the specified name. */
  349. int jas_image_strtofmt(char *s);
  350. /* Get the name of the image format with the specified ID. */
  351. char *jas_image_fmttostr(int fmt);
  352. /* Lookup image format information by the format ID. */
  353. jas_image_fmtinfo_t *jas_image_lookupfmtbyid(int id);
  354. /* Lookup image format information by the format name. */
  355. jas_image_fmtinfo_t *jas_image_lookupfmtbyname(const char *name);
  356. /* Guess the format of an image file based on its name. */
  357. int jas_image_fmtfromname(char *filename);
  358. /* Get the format of image data in a stream. */
  359. int jas_image_getfmt(jas_stream_t *in);
  360. #define jas_image_cmprof(image) ((image)->cmprof_)
  361. int jas_image_ishomosamp(jas_image_t *image);
  362. int jas_image_sampcmpt(jas_image_t *image, int cmptno, int newcmptno,
  363. jas_image_coord_t ho, jas_image_coord_t vo, jas_image_coord_t hs,
  364. jas_image_coord_t vs, int sgnd, int prec);
  365. int jas_image_writecmpt2(jas_image_t *image, int cmptno, jas_image_coord_t x,
  366. jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height,
  367. long *buf);
  368. int jas_image_readcmpt2(jas_image_t *image, int cmptno, jas_image_coord_t x,
  369. jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height,
  370. long *buf);
  371. #define jas_image_setcmprof(image, cmprof) ((image)->cmprof_ = cmprof)
  372. jas_image_t *jas_image_chclrspc(jas_image_t *image, jas_cmprof_t *outprof,
  373. int intent);
  374. void jas_image_dump(jas_image_t *image, FILE *out);
  375. /******************************************************************************\
  376. * Image format-dependent operations.
  377. \******************************************************************************/
  378. #if !defined(EXCLUDE_JPG_SUPPORT)
  379. /* Format-dependent operations for JPG support. */
  380. jas_image_t *jpg_decode(jas_stream_t *in, char *optstr);
  381. int jpg_encode(jas_image_t *image, jas_stream_t *out, char *optstr);
  382. int jpg_validate(jas_stream_t *in);
  383. #endif
  384. #if !defined(EXCLUDE_MIF_SUPPORT)
  385. /* Format-dependent operations for MIF support. */
  386. jas_image_t *mif_decode(jas_stream_t *in, char *optstr);
  387. int mif_encode(jas_image_t *image, jas_stream_t *out, char *optstr);
  388. int mif_validate(jas_stream_t *in);
  389. #endif
  390. #if !defined(EXCLUDE_PNM_SUPPORT)
  391. /* Format-dependent operations for PNM support. */
  392. jas_image_t *pnm_decode(jas_stream_t *in, char *optstr);
  393. int pnm_encode(jas_image_t *image, jas_stream_t *out, char *optstr);
  394. int pnm_validate(jas_stream_t *in);
  395. #endif
  396. #if !defined(EXCLUDE_RAS_SUPPORT)
  397. /* Format-dependent operations for Sun Rasterfile support. */
  398. jas_image_t *ras_decode(jas_stream_t *in, char *optstr);
  399. int ras_encode(jas_image_t *image, jas_stream_t *out, char *optstr);
  400. int ras_validate(jas_stream_t *in);
  401. #endif
  402. #if !defined(EXCLUDE_BMP_SUPPORT)
  403. /* Format-dependent operations for BMP support. */
  404. jas_image_t *bmp_decode(jas_stream_t *in, char *optstr);
  405. int bmp_encode(jas_image_t *image, jas_stream_t *out, char *optstr);
  406. int bmp_validate(jas_stream_t *in);
  407. #endif
  408. #if !defined(EXCLUDE_JP2_SUPPORT)
  409. /* Format-dependent operations for JP2 support. */
  410. jas_image_t *jp2_decode(jas_stream_t *in, char *optstr);
  411. int jp2_encode(jas_image_t *image, jas_stream_t *out, char *optstr);
  412. int jp2_validate(jas_stream_t *in);
  413. #endif
  414. #if !defined(EXCLUDE_JPC_SUPPORT)
  415. /* Format-dependent operations for JPEG-2000 code stream support. */
  416. jas_image_t *jpc_decode(jas_stream_t *in, char *optstr);
  417. int jpc_encode(jas_image_t *image, jas_stream_t *out, char *optstr);
  418. int jpc_validate(jas_stream_t *in);
  419. #endif
  420. #if !defined(EXCLUDE_PGX_SUPPORT)
  421. /* Format-dependent operations for PGX support. */
  422. jas_image_t *pgx_decode(jas_stream_t *in, char *optstr);
  423. int pgx_encode(jas_image_t *image, jas_stream_t *out, char *optstr);
  424. int pgx_validate(jas_stream_t *in);
  425. #endif
  426. #ifdef __cplusplus
  427. }
  428. #endif
  429. #endif