You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

png.c 26KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007
  1. /*
  2. * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. */
  19. FILE_LICENCE ( GPL2_OR_LATER );
  20. #include <stdint.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <errno.h>
  24. #include <byteswap.h>
  25. #include <ipxe/umalloc.h>
  26. #include <ipxe/pixbuf.h>
  27. #include <ipxe/deflate.h>
  28. #include <ipxe/png.h>
  29. /** @file
  30. *
  31. * Portable Network Graphics (PNG) format
  32. *
  33. * The PNG format is defined in RFC 2083.
  34. */
  35. /** PNG context */
  36. struct png_context {
  37. /** Offset within image */
  38. size_t offset;
  39. /** Pixel buffer */
  40. struct pixel_buffer *pixbuf;
  41. /** Bit depth */
  42. unsigned int depth;
  43. /** Colour type */
  44. unsigned int colour_type;
  45. /** Number of channels */
  46. unsigned int channels;
  47. /** Number of interlace passes */
  48. unsigned int passes;
  49. /** Palette, in iPXE's pixel buffer format */
  50. uint32_t palette[PNG_PALETTE_COUNT];
  51. /** Decompression buffer for raw PNG data */
  52. struct deflate_chunk raw;
  53. /** Decompressor */
  54. struct deflate deflate;
  55. };
  56. /** A PNG interlace pass */
  57. struct png_interlace {
  58. /** Pass number */
  59. unsigned int pass;
  60. /** X starting indent */
  61. unsigned int x_indent;
  62. /** Y starting indent */
  63. unsigned int y_indent;
  64. /** X stride */
  65. unsigned int x_stride;
  66. /** Y stride */
  67. unsigned int y_stride;
  68. /** Width */
  69. unsigned int width;
  70. /** Height */
  71. unsigned int height;
  72. };
  73. /** PNG file signature */
  74. static struct png_signature png_signature = PNG_SIGNATURE;
  75. /** Number of interlacing passes */
  76. static uint8_t png_interlace_passes[] = {
  77. [PNG_INTERLACE_NONE] = 1,
  78. [PNG_INTERLACE_ADAM7] = 7,
  79. };
  80. /**
  81. * Transcribe PNG chunk type name (for debugging)
  82. *
  83. * @v type Chunk type
  84. * @ret name Chunk type name
  85. */
  86. static const char * png_type_name ( uint32_t type ) {
  87. static union {
  88. uint32_t type;
  89. char name[ sizeof ( uint32_t ) + 1 /* NUL */ ];
  90. } u;
  91. u.type = type;
  92. return u.name;
  93. }
  94. /**
  95. * Calculate PNG interlace pass parameters
  96. *
  97. * @v png PNG context
  98. * @v pass Pass number (0=first pass)
  99. * @v interlace Interlace pass to fill in
  100. */
  101. static void png_interlace ( struct png_context *png, unsigned int pass,
  102. struct png_interlace *interlace ) {
  103. unsigned int grid_width_log2;
  104. unsigned int grid_height_log2;
  105. unsigned int x_indent;
  106. unsigned int y_indent;
  107. unsigned int x_stride_log2;
  108. unsigned int y_stride_log2;
  109. unsigned int x_stride;
  110. unsigned int y_stride;
  111. unsigned int width;
  112. unsigned int height;
  113. /* Sanity check */
  114. assert ( png->passes > 0 );
  115. /* Store pass number */
  116. interlace->pass = pass;
  117. /* Calculate interlace grid dimensions */
  118. grid_width_log2 = ( png->passes / 2 );
  119. grid_height_log2 = ( ( png->passes - 1 ) / 2 );
  120. /* Calculate starting indents */
  121. interlace->x_indent = x_indent =
  122. ( ( pass & 1 ) ?
  123. ( 1 << ( grid_width_log2 - ( pass / 2 ) - 1 ) ) : 0 );
  124. interlace->y_indent = y_indent =
  125. ( ( pass && ! ( pass & 1 ) ) ?
  126. ( 1 << ( grid_height_log2 - ( ( pass - 1 ) / 2 ) - 1 ) ) : 0);
  127. /* Calculate strides */
  128. x_stride_log2 = ( grid_width_log2 - ( pass / 2 ) );
  129. y_stride_log2 =
  130. ( grid_height_log2 - ( pass ? ( ( pass - 1 ) / 2 ) : 0 ) );
  131. interlace->x_stride = x_stride = ( 1 << x_stride_log2 );
  132. interlace->y_stride = y_stride = ( 1 << y_stride_log2 );
  133. /* Calculate pass dimensions */
  134. width = png->pixbuf->width;
  135. height = png->pixbuf->height;
  136. interlace->width =
  137. ( ( width - x_indent + x_stride - 1 ) >> x_stride_log2 );
  138. interlace->height =
  139. ( ( height - y_indent + y_stride - 1 ) >> y_stride_log2 );
  140. }
  141. /**
  142. * Calculate PNG pixel length
  143. *
  144. * @v png PNG context
  145. * @ret pixel_len Pixel length
  146. */
  147. static unsigned int png_pixel_len ( struct png_context *png ) {
  148. return ( ( ( png->channels * png->depth ) + 7 ) / 8 );
  149. }
  150. /**
  151. * Calculate PNG scanline length
  152. *
  153. * @v png PNG context
  154. * @v interlace Interlace pass
  155. * @ret scanline_len Scanline length (including filter byte)
  156. */
  157. static size_t png_scanline_len ( struct png_context *png,
  158. struct png_interlace *interlace ) {
  159. return ( 1 /* Filter byte */ +
  160. ( ( interlace->width * png->channels * png->depth ) + 7 ) / 8);
  161. }
  162. /**
  163. * Handle PNG image header chunk
  164. *
  165. * @v image PNG image
  166. * @v png PNG context
  167. * @v len Chunk length
  168. * @ret rc Return status code
  169. */
  170. static int png_image_header ( struct image *image, struct png_context *png,
  171. size_t len ) {
  172. struct png_image_header ihdr;
  173. struct png_interlace interlace;
  174. unsigned int pass;
  175. /* Sanity check */
  176. if ( len != sizeof ( ihdr ) ) {
  177. DBGC ( image, "PNG %s invalid IHDR length %zd\n",
  178. image->name, len );
  179. return -EINVAL;
  180. }
  181. if ( png->pixbuf ) {
  182. DBGC ( image, "PNG %s duplicate IHDR\n", image->name );
  183. return -EINVAL;
  184. }
  185. /* Extract image header */
  186. copy_from_user ( &ihdr, image->data, png->offset, len );
  187. DBGC ( image, "PNG %s %dx%d depth %d type %d compression %d filter %d "
  188. "interlace %d\n", image->name, ntohl ( ihdr.width ),
  189. ntohl ( ihdr.height ), ihdr.depth, ihdr.colour_type,
  190. ihdr.compression, ihdr.filter, ihdr.interlace );
  191. /* Sanity checks */
  192. if ( ihdr.compression >= PNG_COMPRESSION_UNKNOWN ) {
  193. DBGC ( image, "PNG %s unknown compression method %d\n",
  194. image->name, ihdr.compression );
  195. return -ENOTSUP;
  196. }
  197. if ( ihdr.filter >= PNG_FILTER_UNKNOWN ) {
  198. DBGC ( image, "PNG %s unknown filter method %d\n",
  199. image->name, ihdr.filter );
  200. return -ENOTSUP;
  201. }
  202. if ( ihdr.interlace >= PNG_INTERLACE_UNKNOWN ) {
  203. DBGC ( image, "PNG %s unknown interlace method %d\n",
  204. image->name, ihdr.interlace );
  205. return -ENOTSUP;
  206. }
  207. /* Allocate pixel buffer */
  208. png->pixbuf = alloc_pixbuf ( ntohl ( ihdr.width ),
  209. ntohl ( ihdr.height ) );
  210. if ( ! png->pixbuf ) {
  211. DBGC ( image, "PNG %s could not allocate pixel buffer\n",
  212. image->name );
  213. return -ENOMEM;
  214. }
  215. /* Extract bit depth */
  216. png->depth = ihdr.depth;
  217. if ( ( png->depth == 0 ) ||
  218. ( ( png->depth & ( png->depth - 1 ) ) != 0 ) ) {
  219. DBGC ( image, "PNG %s invalid depth %d\n",
  220. image->name, png->depth );
  221. return -EINVAL;
  222. }
  223. /* Calculate number of channels */
  224. png->colour_type = ihdr.colour_type;
  225. png->channels = 1;
  226. if ( ! ( ihdr.colour_type & PNG_COLOUR_TYPE_PALETTE ) ) {
  227. if ( ihdr.colour_type & PNG_COLOUR_TYPE_RGB )
  228. png->channels += 2;
  229. if ( ihdr.colour_type & PNG_COLOUR_TYPE_ALPHA )
  230. png->channels += 1;
  231. }
  232. /* Calculate number of interlace passes */
  233. png->passes = png_interlace_passes[ihdr.interlace];
  234. /* Calculate length of raw data buffer */
  235. for ( pass = 0 ; pass < png->passes ; pass++ ) {
  236. png_interlace ( png, pass, &interlace );
  237. if ( interlace.width == 0 )
  238. continue;
  239. png->raw.len += ( interlace.height *
  240. png_scanline_len ( png, &interlace ) );
  241. }
  242. /* Allocate raw data buffer */
  243. png->raw.data = umalloc ( png->raw.len );
  244. if ( ! png->raw.data ) {
  245. DBGC ( image, "PNG %s could not allocate data buffer\n",
  246. image->name );
  247. return -ENOMEM;
  248. }
  249. return 0;
  250. }
  251. /**
  252. * Handle PNG palette chunk
  253. *
  254. * @v image PNG image
  255. * @v png PNG context
  256. * @v len Chunk length
  257. * @ret rc Return status code
  258. */
  259. static int png_palette ( struct image *image, struct png_context *png,
  260. size_t len ) {
  261. size_t offset = png->offset;
  262. struct png_palette_entry palette;
  263. unsigned int i;
  264. /* Populate palette */
  265. for ( i = 0 ; i < ( sizeof ( png->palette ) /
  266. sizeof ( png->palette[0] ) ) ; i++ ) {
  267. /* Stop when we run out of palette data */
  268. if ( len < sizeof ( palette ) )
  269. break;
  270. /* Extract palette entry */
  271. copy_from_user ( &palette, image->data, offset,
  272. sizeof ( palette ) );
  273. png->palette[i] = ( ( palette.red << 16 ) |
  274. ( palette.green << 8 ) |
  275. ( palette.blue << 0 ) );
  276. DBGC2 ( image, "PNG %s palette entry %d is %#06x\n",
  277. image->name, i, png->palette[i] );
  278. /* Move to next entry */
  279. offset += sizeof ( palette );
  280. len -= sizeof ( palette );
  281. }
  282. return 0;
  283. }
  284. /**
  285. * Handle PNG image data chunk
  286. *
  287. * @v image PNG image
  288. * @v png PNG context
  289. * @v len Chunk length
  290. * @ret rc Return status code
  291. */
  292. static int png_image_data ( struct image *image, struct png_context *png,
  293. size_t len ) {
  294. struct deflate_chunk in;
  295. int rc;
  296. /* Deflate this chunk */
  297. deflate_chunk_init ( &in, image->data, png->offset,
  298. ( png->offset + len ) );
  299. if ( ( rc = deflate_inflate ( &png->deflate, &in, &png->raw ) ) != 0 ) {
  300. DBGC ( image, "PNG %s could not decompress: %s\n",
  301. image->name, strerror ( rc ) );
  302. return rc;
  303. }
  304. return 0;
  305. }
  306. /**
  307. * Unfilter byte using the "None" filter
  308. *
  309. * @v current Filtered current byte
  310. * @v left Unfiltered left byte
  311. * @v above Unfiltered above byte
  312. * @v above_left Unfiltered above-left byte
  313. * @ret current Unfiltered current byte
  314. */
  315. static unsigned int png_unfilter_none ( unsigned int current,
  316. unsigned int left __unused,
  317. unsigned int above __unused,
  318. unsigned int above_left __unused ) {
  319. return current;
  320. }
  321. /**
  322. * Unfilter byte using the "Sub" filter
  323. *
  324. * @v current Filtered current byte
  325. * @v left Unfiltered left byte
  326. * @v above Unfiltered above byte
  327. * @v above_left Unfiltered above-left byte
  328. * @ret current Unfiltered current byte
  329. */
  330. static unsigned int png_unfilter_sub ( unsigned int current,
  331. unsigned int left,
  332. unsigned int above __unused,
  333. unsigned int above_left __unused ) {
  334. return ( current + left );
  335. }
  336. /**
  337. * Unfilter byte using the "Up" filter
  338. *
  339. * @v current Filtered current byte
  340. * @v left Unfiltered left byte
  341. * @v above Unfiltered above byte
  342. * @v above_left Unfiltered above-left byte
  343. * @ret current Unfiltered current byte
  344. */
  345. static unsigned int png_unfilter_up ( unsigned int current,
  346. unsigned int left __unused,
  347. unsigned int above,
  348. unsigned int above_left __unused ) {
  349. return ( current + above );
  350. }
  351. /**
  352. * Unfilter byte using the "Average" filter
  353. *
  354. * @v current Filtered current byte
  355. * @v left Unfiltered left byte
  356. * @v above Unfiltered above byte
  357. * @v above_left Unfiltered above-left byte
  358. * @ret current Unfiltered current byte
  359. */
  360. static unsigned int png_unfilter_average ( unsigned int current,
  361. unsigned int left,
  362. unsigned int above,
  363. unsigned int above_left __unused ) {
  364. return ( current + ( ( above + left ) >> 1 ) );
  365. }
  366. /**
  367. * Paeth predictor function (defined in RFC 2083)
  368. *
  369. * @v a Pixel A
  370. * @v b Pixel B
  371. * @v c Pixel C
  372. * @ret predictor Predictor pixel
  373. */
  374. static unsigned int png_paeth_predictor ( unsigned int a, unsigned int b,
  375. unsigned int c ) {
  376. unsigned int p;
  377. unsigned int pa;
  378. unsigned int pb;
  379. unsigned int pc;
  380. /* Algorithm as defined in RFC 2083 section 6.6 */
  381. p = ( a + b - c );
  382. pa = abs ( p - a );
  383. pb = abs ( p - b );
  384. pc = abs ( p - c );
  385. if ( ( pa <= pb ) && ( pa <= pc ) ) {
  386. return a;
  387. } else if ( pb <= pc ) {
  388. return b;
  389. } else {
  390. return c;
  391. }
  392. }
  393. /**
  394. * Unfilter byte using the "Paeth" filter
  395. *
  396. * @v current Filtered current byte
  397. * @v above_left Unfiltered above-left byte
  398. * @v above Unfiltered above byte
  399. * @v left Unfiltered left byte
  400. * @ret current Unfiltered current byte
  401. */
  402. static unsigned int png_unfilter_paeth ( unsigned int current,
  403. unsigned int left,
  404. unsigned int above,
  405. unsigned int above_left ) {
  406. return ( current + png_paeth_predictor ( left, above, above_left ) );
  407. }
  408. /** A PNG filter */
  409. struct png_filter {
  410. /**
  411. * Unfilter byte
  412. *
  413. * @v current Filtered current byte
  414. * @v left Unfiltered left byte
  415. * @v above Unfiltered above byte
  416. * @v above_left Unfiltered above-left byte
  417. * @ret current Unfiltered current byte
  418. */
  419. unsigned int ( * unfilter ) ( unsigned int current,
  420. unsigned int left,
  421. unsigned int above,
  422. unsigned int above_left );
  423. };
  424. /** PNG filter types */
  425. static struct png_filter png_filters[] = {
  426. [PNG_FILTER_BASIC_NONE] = { png_unfilter_none },
  427. [PNG_FILTER_BASIC_SUB] = { png_unfilter_sub },
  428. [PNG_FILTER_BASIC_UP] = { png_unfilter_up },
  429. [PNG_FILTER_BASIC_AVERAGE] = { png_unfilter_average },
  430. [PNG_FILTER_BASIC_PAETH] = { png_unfilter_paeth },
  431. };
  432. /**
  433. * Unfilter one interlace pass of PNG raw data
  434. *
  435. * @v image PNG image
  436. * @v png PNG context
  437. * @v interlace Interlace pass
  438. * @ret rc Return status code
  439. *
  440. * This routine may assume that it is impossible to overrun the raw
  441. * data buffer, since the size is determined by the image dimensions.
  442. */
  443. static int png_unfilter_pass ( struct image *image, struct png_context *png,
  444. struct png_interlace *interlace ) {
  445. size_t offset = png->raw.offset;
  446. size_t pixel_len = png_pixel_len ( png );
  447. size_t scanline_len = png_scanline_len ( png, interlace );
  448. struct png_filter *filter;
  449. unsigned int scanline;
  450. unsigned int byte;
  451. uint8_t filter_type;
  452. uint8_t left;
  453. uint8_t above;
  454. uint8_t above_left;
  455. uint8_t current;
  456. /* On the first scanline of a pass, above bytes are assumed to
  457. * be zero.
  458. */
  459. above = 0;
  460. /* Iterate over each scanline in turn */
  461. for ( scanline = 0 ; scanline < interlace->height ; scanline++ ) {
  462. /* Extract filter byte and determine filter type */
  463. copy_from_user ( &filter_type, png->raw.data, offset++,
  464. sizeof ( filter_type ) );
  465. if ( filter_type >= ( sizeof ( png_filters ) /
  466. sizeof ( png_filters[0] ) ) ) {
  467. DBGC ( image, "PNG %s unknown filter type %d\n",
  468. image->name, filter_type );
  469. return -ENOTSUP;
  470. }
  471. filter = &png_filters[filter_type];
  472. assert ( filter->unfilter != NULL );
  473. DBGC2 ( image, "PNG %s pass %d scanline %d filter type %d\n",
  474. image->name, interlace->pass, scanline, filter_type );
  475. /* At the start of a line, both above-left and left
  476. * bytes are taken to be zero.
  477. */
  478. left = 0;
  479. above_left = 0;
  480. /* Iterate over each byte (not pixel) in turn */
  481. for ( byte = 0 ; byte < ( scanline_len - 1 ) ; byte++ ) {
  482. /* Extract predictor bytes, if applicable */
  483. if ( byte >= pixel_len ) {
  484. copy_from_user ( &left, png->raw.data,
  485. ( offset - pixel_len ),
  486. sizeof ( left ) );
  487. }
  488. if ( scanline > 0 ) {
  489. copy_from_user ( &above, png->raw.data,
  490. ( offset - scanline_len ),
  491. sizeof ( above ) );
  492. }
  493. if ( ( scanline > 0 ) && ( byte >= pixel_len ) ) {
  494. copy_from_user ( &above_left, png->raw.data,
  495. ( offset - scanline_len -
  496. pixel_len ),
  497. sizeof ( above_left ) );
  498. }
  499. /* Unfilter current byte */
  500. copy_from_user ( &current, png->raw.data,
  501. offset, sizeof ( current ) );
  502. current = filter->unfilter ( current, left, above,
  503. above_left );
  504. copy_to_user ( png->raw.data, offset++,
  505. &current, sizeof ( current ) );
  506. }
  507. }
  508. /* Update offset */
  509. png->raw.offset = offset;
  510. return 0;
  511. }
  512. /**
  513. * Unfilter PNG raw data
  514. *
  515. * @v image PNG image
  516. * @v png PNG context
  517. * @ret rc Return status code
  518. *
  519. * This routine may assume that it is impossible to overrun the raw
  520. * data buffer, since the size is determined by the image dimensions.
  521. */
  522. static int png_unfilter ( struct image *image, struct png_context *png ) {
  523. struct png_interlace interlace;
  524. unsigned int pass;
  525. int rc;
  526. /* Process each interlace pass */
  527. png->raw.offset = 0;
  528. for ( pass = 0 ; pass < png->passes ; pass++ ) {
  529. /* Calculate interlace pass parameters */
  530. png_interlace ( png, pass, &interlace );
  531. /* Skip zero-width rows (which have no filter bytes) */
  532. if ( interlace.width == 0 )
  533. continue;
  534. /* Unfilter this pass */
  535. if ( ( rc = png_unfilter_pass ( image, png,
  536. &interlace ) ) != 0 )
  537. return rc;
  538. }
  539. assert ( png->raw.offset == png->raw.len );
  540. return 0;
  541. }
  542. /**
  543. * Calculate PNG pixel component value
  544. *
  545. * @v raw Raw component value
  546. * @v alpha Alpha value
  547. * @v max Maximum raw/alpha value
  548. * @ret value Component value in range 0-255
  549. */
  550. static inline unsigned int png_pixel ( unsigned int raw, unsigned int alpha,
  551. unsigned int max ) {
  552. /* The basic calculation is 255*(raw/max)*(value/max). We use
  553. * fixed-point arithmetic (scaling up to the maximum range for
  554. * a 32-bit integer), in order to get the same results for
  555. * alpha blending as the test cases (produced using
  556. * ImageMagick).
  557. */
  558. return ( ( ( ( ( 0xff00 * raw * alpha ) / max ) / max ) + 0x80 ) >> 8 );
  559. }
  560. /**
  561. * Fill one interlace pass of PNG pixels
  562. *
  563. * @v image PNG image
  564. * @v png PNG context
  565. * @v interlace Interlace pass
  566. *
  567. * This routine may assume that it is impossible to overrun either the
  568. * raw data buffer or the pixel buffer, since the sizes of both are
  569. * determined by the image dimensions.
  570. */
  571. static void png_pixels_pass ( struct image *image,
  572. struct png_context *png,
  573. struct png_interlace *interlace ) {
  574. size_t raw_offset = png->raw.offset;
  575. uint8_t channel[png->channels];
  576. int is_indexed = ( png->colour_type & PNG_COLOUR_TYPE_PALETTE );
  577. int is_rgb = ( png->colour_type & PNG_COLOUR_TYPE_RGB );
  578. int has_alpha = ( png->colour_type & PNG_COLOUR_TYPE_ALPHA );
  579. size_t pixbuf_y_offset;
  580. size_t pixbuf_offset;
  581. size_t pixbuf_x_stride;
  582. size_t pixbuf_y_stride;
  583. size_t raw_stride;
  584. unsigned int y;
  585. unsigned int x;
  586. unsigned int c;
  587. unsigned int bits;
  588. unsigned int depth;
  589. unsigned int max;
  590. unsigned int alpha;
  591. unsigned int raw;
  592. unsigned int value;
  593. uint8_t current = 0;
  594. uint32_t pixel;
  595. /* We only ever use the top byte of 16-bit pixels. Model this
  596. * as a bit depth of 8 with a stride of more than one.
  597. */
  598. depth = png->depth;
  599. raw_stride = ( ( depth + 7 ) / 8 );
  600. if ( depth > 8 )
  601. depth = 8;
  602. max = ( ( 1 << depth ) - 1 );
  603. /* Calculate pixel buffer offset and strides */
  604. pixbuf_y_offset = ( ( ( interlace->y_indent * png->pixbuf->width ) +
  605. interlace->x_indent ) * sizeof ( pixel ) );
  606. pixbuf_x_stride = ( interlace->x_stride * sizeof ( pixel ) );
  607. pixbuf_y_stride = ( interlace->y_stride * png->pixbuf->width *
  608. sizeof ( pixel ) );
  609. DBGC2 ( image, "PNG %s pass %d %dx%d at (%d,%d) stride (%d,%d)\n",
  610. image->name, interlace->pass, interlace->width,
  611. interlace->height, interlace->x_indent, interlace->y_indent,
  612. interlace->x_stride, interlace->y_stride );
  613. /* Iterate over each scanline in turn */
  614. for ( y = 0 ; y < interlace->height ; y++ ) {
  615. /* Skip filter byte */
  616. raw_offset++;
  617. /* Iterate over each pixel in turn */
  618. bits = depth;
  619. pixbuf_offset = pixbuf_y_offset;
  620. for ( x = 0 ; x < interlace->width ; x++ ) {
  621. /* Extract sample value */
  622. for ( c = 0 ; c < png->channels ; c++ ) {
  623. /* Get sample value into high bits of current */
  624. current <<= depth;
  625. bits -= depth;
  626. if ( ! bits ) {
  627. copy_from_user ( &current,
  628. png->raw.data,
  629. raw_offset,
  630. sizeof ( current ) );
  631. raw_offset += raw_stride;
  632. bits = 8;
  633. }
  634. /* Extract sample value */
  635. channel[c] = ( current >> ( 8 - depth ) );
  636. }
  637. /* Convert to native pixel format */
  638. if ( is_indexed ) {
  639. /* Indexed */
  640. pixel = png->palette[channel[0]];
  641. } else {
  642. /* Determine alpha value */
  643. alpha = ( has_alpha ?
  644. channel[ png->channels - 1 ] : max );
  645. /* Convert to RGB value */
  646. pixel = 0;
  647. for ( c = 0 ; c < 3 ; c++ ) {
  648. raw = channel[ is_rgb ? c : 0 ];
  649. value = png_pixel ( raw, alpha, max );
  650. assert ( value <= 255 );
  651. pixel = ( ( pixel << 8 ) | value );
  652. }
  653. }
  654. /* Store pixel */
  655. copy_to_user ( png->pixbuf->data, pixbuf_offset,
  656. &pixel, sizeof ( pixel ) );
  657. pixbuf_offset += pixbuf_x_stride;
  658. }
  659. /* Move to next output row */
  660. pixbuf_y_offset += pixbuf_y_stride;
  661. }
  662. /* Update offset */
  663. png->raw.offset = raw_offset;
  664. }
  665. /**
  666. * Fill PNG pixels
  667. *
  668. * @v image PNG image
  669. * @v png PNG context
  670. *
  671. * This routine may assume that it is impossible to overrun either the
  672. * raw data buffer or the pixel buffer, since the sizes of both are
  673. * determined by the image dimensions.
  674. */
  675. static void png_pixels ( struct image *image, struct png_context *png ) {
  676. struct png_interlace interlace;
  677. unsigned int pass;
  678. /* Process each interlace pass */
  679. png->raw.offset = 0;
  680. for ( pass = 0 ; pass < png->passes ; pass++ ) {
  681. /* Calculate interlace pass parameters */
  682. png_interlace ( png, pass, &interlace );
  683. /* Skip zero-width rows (which have no filter bytes) */
  684. if ( interlace.width == 0 )
  685. continue;
  686. /* Unfilter this pass */
  687. png_pixels_pass ( image, png, &interlace );
  688. }
  689. assert ( png->raw.offset == png->raw.len );
  690. }
  691. /**
  692. * Handle PNG image end chunk
  693. *
  694. * @v image PNG image
  695. * @v png PNG context
  696. * @v len Chunk length
  697. * @ret rc Return status code
  698. */
  699. static int png_image_end ( struct image *image, struct png_context *png,
  700. size_t len ) {
  701. int rc;
  702. /* Sanity checks */
  703. if ( len != 0 ) {
  704. DBGC ( image, "PNG %s invalid IEND length %zd\n",
  705. image->name, len );
  706. return -EINVAL;
  707. }
  708. if ( ! png->pixbuf ) {
  709. DBGC ( image, "PNG %s missing pixel buffer (no IHDR?)\n",
  710. image->name );
  711. return -EINVAL;
  712. }
  713. if ( ! deflate_finished ( &png->deflate ) ) {
  714. DBGC ( image, "PNG %s decompression not complete\n",
  715. image->name );
  716. return -EINVAL;
  717. }
  718. if ( png->raw.offset != png->raw.len ) {
  719. DBGC ( image, "PNG %s incorrect decompressed length (expected "
  720. "%zd, got %zd)\n", image->name, png->raw.len,
  721. png->raw.offset );
  722. return -EINVAL;
  723. }
  724. /* Unfilter raw data */
  725. if ( ( rc = png_unfilter ( image, png ) ) != 0 )
  726. return rc;
  727. /* Fill pixel buffer */
  728. png_pixels ( image, png );
  729. return 0;
  730. }
  731. /** A PNG chunk handler */
  732. struct png_chunk_handler {
  733. /** Chunk type */
  734. uint32_t type;
  735. /**
  736. * Handle chunk
  737. *
  738. * @v image PNG image
  739. * @v png PNG context
  740. * @v len Chunk length
  741. * @ret rc Return status code
  742. */
  743. int ( * handle ) ( struct image *image, struct png_context *png,
  744. size_t len );
  745. };
  746. /** PNG chunk handlers */
  747. static struct png_chunk_handler png_chunk_handlers[] = {
  748. { htonl ( PNG_TYPE_IHDR ), png_image_header },
  749. { htonl ( PNG_TYPE_PLTE ), png_palette },
  750. { htonl ( PNG_TYPE_IDAT ), png_image_data },
  751. { htonl ( PNG_TYPE_IEND ), png_image_end },
  752. };
  753. /**
  754. * Handle PNG chunk
  755. *
  756. * @v image PNG image
  757. * @v png PNG context
  758. * @v type Chunk type
  759. * @v len Chunk length
  760. * @ret rc Return status code
  761. */
  762. static int png_chunk ( struct image *image, struct png_context *png,
  763. uint32_t type, size_t len ) {
  764. struct png_chunk_handler *handler;
  765. unsigned int i;
  766. DBGC ( image, "PNG %s chunk type %s offset %zd length %zd\n",
  767. image->name, png_type_name ( type ), png->offset, len );
  768. /* Handle according to chunk type */
  769. for ( i = 0 ; i < ( sizeof ( png_chunk_handlers ) /
  770. sizeof ( png_chunk_handlers[0] ) ) ; i++ ) {
  771. handler = &png_chunk_handlers[i];
  772. if ( handler->type == type )
  773. return handler->handle ( image, png, len );
  774. }
  775. /* Fail if unknown chunk type is critical */
  776. if ( ! ( type & htonl ( PNG_CHUNK_ANCILLARY ) ) ) {
  777. DBGC ( image, "PNG %s unknown critical chunk type %s\n",
  778. image->name, png_type_name ( type ) );
  779. return -ENOTSUP;
  780. }
  781. /* Ignore non-critical unknown chunk types */
  782. return 0;
  783. }
  784. /**
  785. * Convert PNG image to pixel buffer
  786. *
  787. * @v image PNG image
  788. * @v pixbuf Pixel buffer to fill in
  789. * @ret rc Return status code
  790. */
  791. static int png_pixbuf ( struct image *image, struct pixel_buffer **pixbuf ) {
  792. struct png_context *png;
  793. struct png_chunk_header header;
  794. struct png_chunk_footer footer;
  795. size_t remaining;
  796. size_t chunk_len;
  797. int rc;
  798. /* Allocate and initialise context */
  799. png = zalloc ( sizeof ( *png ) );
  800. if ( ! png ) {
  801. rc = -ENOMEM;
  802. goto err_alloc;
  803. }
  804. png->offset = sizeof ( struct png_signature );
  805. deflate_init ( &png->deflate, DEFLATE_ZLIB );
  806. /* Process chunks */
  807. do {
  808. /* Extract chunk header */
  809. remaining = ( image->len - png->offset );
  810. if ( remaining < sizeof ( header ) ) {
  811. DBGC ( image, "PNG %s truncated chunk header at offset "
  812. "%zd\n", image->name, png->offset );
  813. rc = -EINVAL;
  814. goto err_truncated;
  815. }
  816. copy_from_user ( &header, image->data, png->offset,
  817. sizeof ( header ) );
  818. png->offset += sizeof ( header );
  819. /* Validate chunk length */
  820. chunk_len = ntohl ( header.len );
  821. if ( remaining < ( sizeof ( header ) + chunk_len +
  822. sizeof ( footer ) ) ) {
  823. DBGC ( image, "PNG %s truncated chunk data/footer at "
  824. "offset %zd\n", image->name, png->offset );
  825. rc = -EINVAL;
  826. goto err_truncated;
  827. }
  828. /* Handle chunk */
  829. if ( ( rc = png_chunk ( image, png, header.type,
  830. chunk_len ) ) != 0 )
  831. goto err_chunk;
  832. /* Move to next chunk */
  833. png->offset += ( chunk_len + sizeof ( footer ) );
  834. } while ( png->offset < image->len );
  835. /* Check that we finished with an IEND chunk */
  836. if ( header.type != htonl ( PNG_TYPE_IEND ) ) {
  837. DBGC ( image, "PNG %s did not finish with IEND\n",
  838. image->name );
  839. rc = -EINVAL;
  840. goto err_iend;
  841. }
  842. /* Return pixel buffer */
  843. *pixbuf = pixbuf_get ( png->pixbuf );
  844. /* Success */
  845. rc = 0;
  846. err_iend:
  847. err_chunk:
  848. err_truncated:
  849. pixbuf_put ( png->pixbuf );
  850. ufree ( png->raw.data );
  851. free ( png );
  852. err_alloc:
  853. return rc;
  854. }
  855. /**
  856. * Probe PNG image
  857. *
  858. * @v image PNG image
  859. * @ret rc Return status code
  860. */
  861. static int png_probe ( struct image *image ) {
  862. struct png_signature signature;
  863. /* Sanity check */
  864. if ( image->len < sizeof ( signature ) ) {
  865. DBGC ( image, "PNG %s is too short\n", image->name );
  866. return -ENOEXEC;
  867. }
  868. /* Check signature */
  869. copy_from_user ( &signature, image->data, 0, sizeof ( signature ) );
  870. if ( memcmp ( &signature, &png_signature, sizeof ( signature ) ) != 0 ){
  871. DBGC ( image, "PNG %s has invalid signature\n", image->name );
  872. return -ENOEXEC;
  873. }
  874. return 0;
  875. }
  876. /** PNG image type */
  877. struct image_type png_image_type __image_type ( PROBE_NORMAL ) = {
  878. .name = "PNG",
  879. .probe = png_probe,
  880. .pixbuf = png_pixbuf,
  881. };