image.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. /*Daala video codec
  2. Copyright (c) 2004-2012 Daala project contributors. All rights reserved.
  3. Redistribution and use in source and binary forms, with or without
  4. modification, are permitted provided that the following conditions are met:
  5. - Redistributions of source code must retain the above copyright notice, this
  6. list of conditions and the following disclaimer.
  7. - Redistributions in binary form must reproduce the above copyright notice,
  8. this list of conditions and the following disclaimer in the documentation
  9. and/or other materials provided with the distribution.
  10. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
  11. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  12. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  13. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
  14. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  15. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  16. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  17. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  18. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  19. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
  20. #ifdef HAVE_CONFIG_H
  21. #include "config.h"
  22. #endif
  23. #include "image.h"
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <errno.h>
  28. #include <png.h>
  29. #include <zlib.h>
  30. #include <ogg/os_types.h>
  31. #include <limits.h>
  32. static void **od_malloc_2d(size_t _height,size_t _width,size_t _sz){
  33. size_t rowsz;
  34. size_t colsz;
  35. size_t datsz;
  36. char *ret;
  37. colsz=_height*sizeof(void *);
  38. rowsz=_sz*_width;
  39. datsz=rowsz*_height;
  40. /*Alloc array and row pointers.*/
  41. ret=(char *)_ogg_malloc(datsz+colsz);
  42. /*Initialize the array.*/
  43. if(ret!=NULL){
  44. size_t i;
  45. void **p;
  46. char *datptr;
  47. p=(void **)ret;
  48. i=_height;
  49. for(datptr=ret+colsz;i-->0;p++,datptr+=rowsz)*p=(void *)datptr;
  50. }
  51. return (void **)ret;
  52. }
  53. static void od_free_2d(void *_ptr){
  54. _ogg_free(_ptr);
  55. }
  56. static void png_read(png_structp _png,png_bytep _data,png_size_t _sz){
  57. size_t ret;
  58. ret=fread(_data,_sz,1,(FILE *)png_get_io_ptr(_png));
  59. if(ret!=1)png_error(_png,"Read Error");
  60. }
  61. int od_rgba16_image_read_png(od_rgba16_image *_this,FILE *_fin){
  62. unsigned char header[8];
  63. png_structp png;
  64. png_infop info;
  65. png_infop end;
  66. od_rgba16_pixel *data;
  67. png_bytep *rows;
  68. png_color_16p bkgd;
  69. png_uint_32 width;
  70. png_uint_32 height;
  71. int bit_depth;
  72. int color_type;
  73. int interlace_type;
  74. int compression_type;
  75. int filter_method;
  76. png_uint_32 i;
  77. png_uint_32 j;
  78. if(fread(header,8,1,_fin)<1){
  79. fprintf(stderr,"Error reading from file.\n");
  80. return -EINVAL;
  81. }
  82. if(png_sig_cmp(header,0,8)){
  83. fprintf(stderr,"Error: Not a PNG.\n");
  84. return -EINVAL;
  85. }
  86. png=png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
  87. if(png==NULL){
  88. fprintf(stderr,"Error: %s\n",strerror(ENOMEM));
  89. return -ENOMEM;
  90. }
  91. info=png_create_info_struct(png);
  92. if(info==NULL){
  93. fprintf(stderr,"Error: %s\n",strerror(ENOMEM));
  94. png_destroy_read_struct(&png,NULL,NULL);
  95. return -ENOMEM;
  96. }
  97. end=png_create_info_struct(png);
  98. if(end==NULL){
  99. fprintf(stderr,"Error: %s\n",strerror(ENOMEM));
  100. png_destroy_read_struct(&png,&info,NULL);
  101. return -EINVAL;
  102. }
  103. rows=NULL;
  104. data=NULL;
  105. if(setjmp(png_jmpbuf(png))){
  106. png_free(png,rows);
  107. free(data);
  108. png_destroy_read_struct(&png,&info,&end);
  109. return -EINVAL;
  110. }
  111. png_set_read_fn(png,_fin,png_read);
  112. png_set_sig_bytes(png,8);
  113. png_read_info(png,info);
  114. png_get_IHDR(png,info,&width,&height,&bit_depth,&color_type,
  115. &interlace_type,&compression_type,&filter_method);
  116. if(width<=0||height<=0||width>INT_MAX||height>INT_MAX||
  117. width*(png_size_t)height*8>INT_MAX||
  118. width*(png_size_t)height*8/height/8!=width){
  119. png_destroy_read_struct(&png,&info,&end);
  120. return -EINVAL;
  121. }
  122. png_set_expand(png);
  123. if(bit_depth<8)png_set_packing(png);
  124. if(!(color_type&PNG_COLOR_MASK_COLOR))png_set_gray_to_rgb(png);
  125. if(png_get_bKGD(png,info,&bkgd)){
  126. png_set_background(png,bkgd,PNG_BACKGROUND_GAMMA_FILE,1,1.0);
  127. }
  128. /*Add an alpha channel if the image doesn't contain one.*/
  129. png_set_add_alpha(png,0xFFFF,PNG_FILLER_AFTER);
  130. data=(od_rgba16_pixel *)_ogg_malloc(height*width*sizeof(*data));
  131. rows=(png_bytep *)png_malloc(png,height*sizeof(*rows));
  132. for(j=0;j<height;j++)rows[j]=(png_bytep)(data+j*width);
  133. png_read_image(png,rows);
  134. png_read_end(png,end);
  135. if(bit_depth<16){
  136. /*If the image wasn't 16-bit, expand it so it is.
  137. We do this by duplicating the high byte, so that, e.g., 0 maps to 0 and
  138. 255 maps to 65535.
  139. This is also nicely endian-independent.*/
  140. for(j=0;j<height;j++){
  141. for(i=4*width;i-->0;)rows[j][2*i]=rows[j][2*i+1]=rows[j][i];
  142. }
  143. }
  144. else{
  145. /*Otherwise, convert from big-endian to host-endian byte order.
  146. Instead of bothering to try to detect endianess, we just always convert.
  147. Since almost all hosts will be little-endian in practice, there's little
  148. to be gained, and this is guaranteed to work portably.*/
  149. for(j=0;j<height;j++){
  150. for(i=width;i-->0;){
  151. unsigned short r;
  152. unsigned short g;
  153. unsigned short b;
  154. unsigned short a;
  155. r=(unsigned short)(rows[j][8*i+0]<<8|rows[j][8*i+1]);
  156. g=(unsigned short)(rows[j][8*i+2]<<8|rows[j][8*i+3]);
  157. b=(unsigned short)(rows[j][8*i+4]<<8|rows[j][8*i+5]);
  158. a=(unsigned short)(rows[j][8*i+6]<<8|rows[j][8*i+7]);
  159. *(data+j*width+i)[0]=r;
  160. *(data+j*width+i)[1]=g;
  161. *(data+j*width+i)[2]=b;
  162. *(data+j*width+i)[3]=a;
  163. }
  164. }
  165. }
  166. png_free(png,rows);
  167. png_destroy_read_struct(&png,&info,&end);
  168. _this->data=data;
  169. _this->stride=(int)width;
  170. _this->width=(int)width;
  171. _this->height=(int)height;
  172. return 0;
  173. }
  174. void od_rgba16_image_init(od_rgba16_image *_this,int _width,int _height){
  175. od_rgba16_pixel *data;
  176. int i;
  177. int j;
  178. data=(od_rgba16_pixel *)_ogg_malloc(_height*_width*sizeof(*data));
  179. for(j=0;j<_height;j++){
  180. for(i=0;i<_width;i++){
  181. (*(data+j*_width+i))[0]=0;
  182. (*(data+j*_width+i))[1]=0;
  183. (*(data+j*_width+i))[2]=0;
  184. (*(data+j*_width+i))[3]=(unsigned short)0xFFFFU;
  185. }
  186. }
  187. _this->data=data;
  188. _this->stride=(int)_width;
  189. _this->width=(int)_width;
  190. _this->height=(int)_height;
  191. }
  192. static void png_write(png_structp _png,png_bytep _data,png_size_t _sz){
  193. size_t ret;
  194. ret=fwrite(_data,_sz,1,(FILE *)png_get_io_ptr(_png));
  195. if(ret!=1)png_error(_png,"Write Error");
  196. }
  197. static void png_flush(png_structp _png){
  198. fflush((FILE *)png_get_io_ptr(_png));
  199. }
  200. int od_rgba16_image_write_png(const od_rgba16_image *_this,FILE *_fout){
  201. png_structp png;
  202. png_infop info;
  203. png_bytep *image;
  204. od_rgba16_pixel *data;
  205. int width;
  206. int height;
  207. int stride;
  208. int i;
  209. int j;
  210. width=_this->width;
  211. height=_this->height;
  212. image=(png_bytep *)od_malloc_2d(height,8*width,sizeof(**image));
  213. if(image==NULL)return -EFAULT;
  214. png=png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
  215. if(png==NULL){
  216. od_free_2d(image);
  217. return -EFAULT;
  218. }
  219. info=png_create_info_struct(png);
  220. if(info==NULL){
  221. png_destroy_write_struct(&png,NULL);
  222. od_free_2d(image);
  223. return -EFAULT;
  224. }
  225. if(setjmp(png_jmpbuf(png))){
  226. png_destroy_write_struct(&png,&info);
  227. od_free_2d(image);
  228. return -EFAULT;
  229. }
  230. data=_this->data;
  231. stride=_this->stride;
  232. for(j=0;j<height;j++){
  233. for(i=0;i<width;i++){
  234. unsigned short r;
  235. unsigned short g;
  236. unsigned short b;
  237. unsigned short a;
  238. r=(*(data+j*stride+i))[0];
  239. g=(*(data+j*stride+i))[1];
  240. b=(*(data+j*stride+i))[2];
  241. a=(*(data+j*stride+i))[3];
  242. image[j][i*8+0]=(png_byte)(r>>8);
  243. image[j][i*8+1]=(png_byte)(r&0xFF);
  244. image[j][i*8+2]=(png_byte)(g>>8);
  245. image[j][i*8+3]=(png_byte)(g&0xFF);
  246. image[j][i*8+4]=(png_byte)(b>>8);
  247. image[j][i*8+5]=(png_byte)(b&0xFF);
  248. image[j][i*8+6]=(png_byte)(a>>8);
  249. image[j][i*8+7]=(png_byte)(a&0xFF);
  250. }
  251. }
  252. png_set_write_fn(png,_fout,png_write,png_flush);
  253. png_set_compression_level(png,Z_DEFAULT_COMPRESSION);
  254. png_set_IHDR(png,info,width,height,16,PNG_COLOR_TYPE_RGBA,
  255. PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
  256. png_set_rows(png,info,image);
  257. png_write_png(png,info,PNG_TRANSFORM_IDENTITY,NULL);
  258. png_write_end(png,info);
  259. png_destroy_write_struct(&png,&info);
  260. od_free_2d(image);
  261. return 0;
  262. }
  263. void od_rgba16_image_draw_point(od_rgba16_image *_this,int _x,int _y,
  264. const od_rgba16_pixel _color){
  265. od_rgba16_pixel *data;
  266. int stride;
  267. int width;
  268. int height;
  269. unsigned short r;
  270. unsigned short g;
  271. unsigned short b;
  272. unsigned short a;
  273. width=_this->width;
  274. height=_this->height;
  275. if(_x<0||_y<0||_x>=width||_y>=height)return;
  276. data=_this->data;
  277. stride=_this->stride;
  278. r=_color[0];
  279. g=_color[1];
  280. b=_color[2];
  281. a=_color[3];
  282. (*(data+stride*_y+_x))[0]=r;
  283. (*(data+stride*_y+_x))[1]=g;
  284. (*(data+stride*_y+_x))[2]=b;
  285. (*(data+stride*_y+_x))[3]=a;
  286. }
  287. void od_rgba16_image_draw_line(od_rgba16_image *_this,
  288. int _x0,int _y0,int _x1,int _y1,const od_rgba16_pixel _color){
  289. int x0[2];
  290. int x1[2];
  291. int dx[2];
  292. int step[2];
  293. int steep;
  294. int err;
  295. int derr;
  296. steep=abs(_y1-_y0)>abs(_x1-_x0);
  297. x0[0]=_x0;
  298. x0[1]=_y0;
  299. x1[0]=_x1;
  300. x1[1]=_y1;
  301. dx[0]=abs(x1[0]-x0[0]);
  302. dx[1]=abs(x1[1]-x0[1]);
  303. err=0;
  304. derr=dx[1-steep];
  305. step[0]=((x0[0]<x1[0])<<1)-1;
  306. step[1]=((x0[1]<x1[1])<<1)-1;
  307. od_rgba16_image_draw_point(_this,x0[0],x0[1],_color);
  308. while(x0[steep]!=x1[steep]){
  309. x0[steep]+=step[steep];
  310. err+=derr;
  311. if(err<<1>dx[steep]){
  312. x0[1-steep]+=step[1-steep];
  313. err-=dx[steep];
  314. }
  315. od_rgba16_image_draw_point(_this,x0[0],x0[1],_color);
  316. }
  317. }
  318. void od_rgba16_image_clear(od_rgba16_image *_this){
  319. _ogg_free(_this->data);
  320. }
  321. void od_rgba16_from_hue(od_rgba16_pixel _color,int _hue){
  322. int h;
  323. int i;
  324. int f;
  325. int y;
  326. h=_hue%HUE_MAX;
  327. if(h<0)h+=HUE_MAX;
  328. i=h/0xFFFF;
  329. f=h-i*0xFFFF;
  330. y=(0xFFFFU*f+0x7FFFU)/0xFFFFU;
  331. switch(i){
  332. case 0:{
  333. _color[0]=(unsigned short)0xFFFFU;
  334. _color[1]=(unsigned short)y;
  335. _color[2]=0;
  336. _color[3]=(unsigned short)0xFFFFU;
  337. }break;
  338. case 1:{
  339. _color[0]=(unsigned short)(0xFFFFU-y);
  340. _color[1]=(unsigned short)0xFFFFU;
  341. _color[2]=0;
  342. _color[3]=(unsigned short)0xFFFFU;
  343. }break;
  344. case 2:{
  345. _color[0]=0;
  346. _color[1]=(unsigned short)0xFFFFU;
  347. _color[2]=(unsigned short)y;
  348. _color[3]=(unsigned short)0xFFFFU;
  349. }break;
  350. case 3:{
  351. _color[0]=0;
  352. _color[1]=(unsigned short)(0xFFFFU-y);
  353. _color[2]=(unsigned short)0xFFFFU;
  354. _color[3]=(unsigned short)0xFFFFU;
  355. }break;
  356. case 4:{
  357. _color[0]=(unsigned short)y;
  358. _color[1]=0;
  359. _color[2]=(unsigned short)0xFFFFU;
  360. _color[3]=(unsigned short)0xFFFFU;
  361. }break;
  362. default:{
  363. _color[0]=(unsigned short)0xFFFFU;
  364. _color[1]=0;
  365. _color[2]=(unsigned short)(0xFFFFU-y);
  366. _color[3]=(unsigned short)0xFFFFU;
  367. }break;
  368. }
  369. }
  370. void intra_map_colors(od_rgba16_pixel *_colors,int _mapi_max){
  371. /*The first mode is always DC mode; use black.*/
  372. _colors[0][0]=(unsigned short)0x0000U;
  373. _colors[0][1]=(unsigned short)0x0000U;
  374. _colors[0][2]=(unsigned short)0x0000U;
  375. _colors[0][3]=(unsigned short)0xFFFFU;
  376. if(_mapi_max>1){
  377. /*The second mode is the "True Motion" mode; use white.*/
  378. _colors[1][0]=(unsigned short)0xFFFFU;
  379. _colors[1][1]=(unsigned short)0xFFFFU;
  380. _colors[1][2]=(unsigned short)0xFFFFU;
  381. _colors[1][3]=(unsigned short)0xFFFFU;
  382. /*Pull out fully saturated colors from the color wheel for all the
  383. directional modes.*/
  384. if(_mapi_max>2){
  385. int dhue;
  386. int mapi;
  387. dhue=HUE_MAX/(_mapi_max-2);
  388. for(mapi=2;mapi<_mapi_max;mapi++){
  389. od_rgba16_from_hue(_colors[mapi],dhue*(mapi-2));
  390. }
  391. }
  392. }
  393. }