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.

427 lines
11KB

  1. /*
  2. * PNM image format
  3. * Copyright (c) 2002, 2003 Fabrice Bellard.
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include "avcodec.h"
  22. #include "pnm.h"
  23. static int common_init(AVCodecContext *avctx){
  24. PNMContext *s = avctx->priv_data;
  25. avcodec_get_frame_defaults((AVFrame*)&s->picture);
  26. avctx->coded_frame= (AVFrame*)&s->picture;
  27. return 0;
  28. }
  29. static int pnm_decode_frame(AVCodecContext *avctx,
  30. void *data, int *data_size,
  31. uint8_t *buf, int buf_size)
  32. {
  33. PNMContext * const s = avctx->priv_data;
  34. AVFrame *picture = data;
  35. AVFrame * const p= (AVFrame*)&s->picture;
  36. int i, n, linesize, h, upgrade = 0;
  37. unsigned char *ptr;
  38. s->bytestream_start=
  39. s->bytestream= buf;
  40. s->bytestream_end= buf + buf_size;
  41. if(ff_pnm_decode_header(avctx, s) < 0)
  42. return -1;
  43. if(p->data[0])
  44. avctx->release_buffer(avctx, p);
  45. p->reference= 0;
  46. if(avctx->get_buffer(avctx, p) < 0){
  47. av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
  48. return -1;
  49. }
  50. p->pict_type= FF_I_TYPE;
  51. p->key_frame= 1;
  52. switch(avctx->pix_fmt) {
  53. default:
  54. return -1;
  55. case PIX_FMT_RGB24:
  56. n = avctx->width * 3;
  57. goto do_read;
  58. case PIX_FMT_GRAY8:
  59. n = avctx->width;
  60. if (s->maxval < 255)
  61. upgrade = 1;
  62. goto do_read;
  63. case PIX_FMT_GRAY16BE:
  64. case PIX_FMT_GRAY16LE:
  65. n = avctx->width * 2;
  66. if (s->maxval < 65535)
  67. upgrade = 2;
  68. goto do_read;
  69. case PIX_FMT_MONOWHITE:
  70. case PIX_FMT_MONOBLACK:
  71. n = (avctx->width + 7) >> 3;
  72. do_read:
  73. ptr = p->data[0];
  74. linesize = p->linesize[0];
  75. if(s->bytestream + n*avctx->height > s->bytestream_end)
  76. return -1;
  77. for(i = 0; i < avctx->height; i++) {
  78. if (!upgrade)
  79. memcpy(ptr, s->bytestream, n);
  80. else if (upgrade == 1) {
  81. unsigned int j, f = (255*128 + s->maxval/2) / s->maxval;
  82. for (j=0; j<n; j++)
  83. ptr[j] = (s->bytestream[j] * f + 64) >> 7;
  84. } else if (upgrade == 2) {
  85. unsigned int j, v, f = (65535*32768 + s->maxval/2) / s->maxval;
  86. for (j=0; j<n/2; j++) {
  87. v = be2me_16(((uint16_t *)s->bytestream)[j]);
  88. ((uint16_t *)ptr)[j] = (v * f + 16384) >> 15;
  89. }
  90. }
  91. s->bytestream += n;
  92. ptr += linesize;
  93. }
  94. break;
  95. case PIX_FMT_YUV420P:
  96. {
  97. unsigned char *ptr1, *ptr2;
  98. n = avctx->width;
  99. ptr = p->data[0];
  100. linesize = p->linesize[0];
  101. if(s->bytestream + n*avctx->height*3/2 > s->bytestream_end)
  102. return -1;
  103. for(i = 0; i < avctx->height; i++) {
  104. memcpy(ptr, s->bytestream, n);
  105. s->bytestream += n;
  106. ptr += linesize;
  107. }
  108. ptr1 = p->data[1];
  109. ptr2 = p->data[2];
  110. n >>= 1;
  111. h = avctx->height >> 1;
  112. for(i = 0; i < h; i++) {
  113. memcpy(ptr1, s->bytestream, n);
  114. s->bytestream += n;
  115. memcpy(ptr2, s->bytestream, n);
  116. s->bytestream += n;
  117. ptr1 += p->linesize[1];
  118. ptr2 += p->linesize[2];
  119. }
  120. }
  121. break;
  122. case PIX_FMT_RGB32:
  123. ptr = p->data[0];
  124. linesize = p->linesize[0];
  125. if(s->bytestream + avctx->width*avctx->height*4 > s->bytestream_end)
  126. return -1;
  127. for(i = 0; i < avctx->height; i++) {
  128. int j, r, g, b, a;
  129. for(j = 0;j < avctx->width; j++) {
  130. r = *s->bytestream++;
  131. g = *s->bytestream++;
  132. b = *s->bytestream++;
  133. a = *s->bytestream++;
  134. ((uint32_t *)ptr)[j] = (a << 24) | (r << 16) | (g << 8) | b;
  135. }
  136. ptr += linesize;
  137. }
  138. break;
  139. }
  140. *picture= *(AVFrame*)&s->picture;
  141. *data_size = sizeof(AVPicture);
  142. return s->bytestream - s->bytestream_start;
  143. }
  144. static int pnm_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, int buf_size, void *data){
  145. PNMContext *s = avctx->priv_data;
  146. AVFrame *pict = data;
  147. AVFrame * const p= (AVFrame*)&s->picture;
  148. int i, h, h1, c, n, linesize;
  149. uint8_t *ptr, *ptr1, *ptr2;
  150. if(buf_size < avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height) + 200){
  151. av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n");
  152. return -1;
  153. }
  154. *p = *pict;
  155. p->pict_type= FF_I_TYPE;
  156. p->key_frame= 1;
  157. s->bytestream_start=
  158. s->bytestream= outbuf;
  159. s->bytestream_end= outbuf+buf_size;
  160. h = avctx->height;
  161. h1 = h;
  162. switch(avctx->pix_fmt) {
  163. case PIX_FMT_MONOWHITE:
  164. c = '4';
  165. n = (avctx->width + 7) >> 3;
  166. break;
  167. case PIX_FMT_GRAY8:
  168. c = '5';
  169. n = avctx->width;
  170. break;
  171. case PIX_FMT_GRAY16BE:
  172. c = '5';
  173. n = avctx->width * 2;
  174. break;
  175. case PIX_FMT_RGB24:
  176. c = '6';
  177. n = avctx->width * 3;
  178. break;
  179. case PIX_FMT_YUV420P:
  180. c = '5';
  181. n = avctx->width;
  182. h1 = (h * 3) / 2;
  183. break;
  184. default:
  185. return -1;
  186. }
  187. snprintf(s->bytestream, s->bytestream_end - s->bytestream,
  188. "P%c\n%d %d\n",
  189. c, avctx->width, h1);
  190. s->bytestream += strlen(s->bytestream);
  191. if (avctx->pix_fmt != PIX_FMT_MONOWHITE) {
  192. snprintf(s->bytestream, s->bytestream_end - s->bytestream,
  193. "%d\n", (avctx->pix_fmt != PIX_FMT_GRAY16BE) ? 255 : 65535);
  194. s->bytestream += strlen(s->bytestream);
  195. }
  196. ptr = p->data[0];
  197. linesize = p->linesize[0];
  198. for(i=0;i<h;i++) {
  199. memcpy(s->bytestream, ptr, n);
  200. s->bytestream += n;
  201. ptr += linesize;
  202. }
  203. if (avctx->pix_fmt == PIX_FMT_YUV420P) {
  204. h >>= 1;
  205. n >>= 1;
  206. ptr1 = p->data[1];
  207. ptr2 = p->data[2];
  208. for(i=0;i<h;i++) {
  209. memcpy(s->bytestream, ptr1, n);
  210. s->bytestream += n;
  211. memcpy(s->bytestream, ptr2, n);
  212. s->bytestream += n;
  213. ptr1 += p->linesize[1];
  214. ptr2 += p->linesize[2];
  215. }
  216. }
  217. return s->bytestream - s->bytestream_start;
  218. }
  219. static int pam_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, int buf_size, void *data){
  220. PNMContext *s = avctx->priv_data;
  221. AVFrame *pict = data;
  222. AVFrame * const p= (AVFrame*)&s->picture;
  223. int i, h, w, n, linesize, depth, maxval;
  224. const char *tuple_type;
  225. uint8_t *ptr;
  226. if(buf_size < avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height) + 200){
  227. av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n");
  228. return -1;
  229. }
  230. *p = *pict;
  231. p->pict_type= FF_I_TYPE;
  232. p->key_frame= 1;
  233. s->bytestream_start=
  234. s->bytestream= outbuf;
  235. s->bytestream_end= outbuf+buf_size;
  236. h = avctx->height;
  237. w = avctx->width;
  238. switch(avctx->pix_fmt) {
  239. case PIX_FMT_MONOWHITE:
  240. n = (w + 7) >> 3;
  241. depth = 1;
  242. maxval = 1;
  243. tuple_type = "BLACKANDWHITE";
  244. break;
  245. case PIX_FMT_GRAY8:
  246. n = w;
  247. depth = 1;
  248. maxval = 255;
  249. tuple_type = "GRAYSCALE";
  250. break;
  251. case PIX_FMT_RGB24:
  252. n = w * 3;
  253. depth = 3;
  254. maxval = 255;
  255. tuple_type = "RGB";
  256. break;
  257. case PIX_FMT_RGB32:
  258. n = w * 4;
  259. depth = 4;
  260. maxval = 255;
  261. tuple_type = "RGB_ALPHA";
  262. break;
  263. default:
  264. return -1;
  265. }
  266. snprintf(s->bytestream, s->bytestream_end - s->bytestream,
  267. "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLETYPE %s\nENDHDR\n",
  268. w, h, depth, maxval, tuple_type);
  269. s->bytestream += strlen(s->bytestream);
  270. ptr = p->data[0];
  271. linesize = p->linesize[0];
  272. if (avctx->pix_fmt == PIX_FMT_RGB32) {
  273. int j;
  274. unsigned int v;
  275. for(i=0;i<h;i++) {
  276. for(j=0;j<w;j++) {
  277. v = ((uint32_t *)ptr)[j];
  278. *s->bytestream++ = v >> 16;
  279. *s->bytestream++ = v >> 8;
  280. *s->bytestream++ = v;
  281. *s->bytestream++ = v >> 24;
  282. }
  283. ptr += linesize;
  284. }
  285. } else {
  286. for(i=0;i<h;i++) {
  287. memcpy(s->bytestream, ptr, n);
  288. s->bytestream += n;
  289. ptr += linesize;
  290. }
  291. }
  292. return s->bytestream - s->bytestream_start;
  293. }
  294. #if 0
  295. static int pnm_probe(AVProbeData *pd)
  296. {
  297. const char *p = pd->buf;
  298. if (pd->buf_size >= 8 &&
  299. p[0] == 'P' &&
  300. p[1] >= '4' && p[1] <= '6' &&
  301. pnm_space(p[2]) )
  302. return AVPROBE_SCORE_MAX - 1; /* to permit pgmyuv probe */
  303. else
  304. return 0;
  305. }
  306. static int pgmyuv_probe(AVProbeData *pd)
  307. {
  308. if (match_ext(pd->filename, "pgmyuv"))
  309. return AVPROBE_SCORE_MAX;
  310. else
  311. return 0;
  312. }
  313. static int pam_probe(AVProbeData *pd)
  314. {
  315. const char *p = pd->buf;
  316. if (pd->buf_size >= 8 &&
  317. p[0] == 'P' &&
  318. p[1] == '7' &&
  319. p[2] == '\n')
  320. return AVPROBE_SCORE_MAX;
  321. else
  322. return 0;
  323. }
  324. #endif
  325. #ifdef CONFIG_PGM_ENCODER
  326. AVCodec pgm_encoder = {
  327. "pgm",
  328. CODEC_TYPE_VIDEO,
  329. CODEC_ID_PGM,
  330. sizeof(PNMContext),
  331. common_init,
  332. pnm_encode_frame,
  333. NULL, //encode_end,
  334. pnm_decode_frame,
  335. .pix_fmts= (enum PixelFormat[]){PIX_FMT_GRAY8, PIX_FMT_GRAY16BE, -1},
  336. };
  337. #endif // CONFIG_PGM_ENCODER
  338. #ifdef CONFIG_PGMYUV_ENCODER
  339. AVCodec pgmyuv_encoder = {
  340. "pgmyuv",
  341. CODEC_TYPE_VIDEO,
  342. CODEC_ID_PGMYUV,
  343. sizeof(PNMContext),
  344. common_init,
  345. pnm_encode_frame,
  346. NULL, //encode_end,
  347. pnm_decode_frame,
  348. .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1},
  349. };
  350. #endif // CONFIG_PGMYUV_ENCODER
  351. #ifdef CONFIG_PPM_ENCODER
  352. AVCodec ppm_encoder = {
  353. "ppm",
  354. CODEC_TYPE_VIDEO,
  355. CODEC_ID_PPM,
  356. sizeof(PNMContext),
  357. common_init,
  358. pnm_encode_frame,
  359. NULL, //encode_end,
  360. pnm_decode_frame,
  361. .pix_fmts= (enum PixelFormat[]){PIX_FMT_RGB24, -1},
  362. };
  363. #endif // CONFIG_PPM_ENCODER
  364. #ifdef CONFIG_PBM_ENCODER
  365. AVCodec pbm_encoder = {
  366. "pbm",
  367. CODEC_TYPE_VIDEO,
  368. CODEC_ID_PBM,
  369. sizeof(PNMContext),
  370. common_init,
  371. pnm_encode_frame,
  372. NULL, //encode_end,
  373. pnm_decode_frame,
  374. .pix_fmts= (enum PixelFormat[]){PIX_FMT_MONOWHITE, -1},
  375. };
  376. #endif // CONFIG_PBM_ENCODER
  377. #ifdef CONFIG_PAM_ENCODER
  378. AVCodec pam_encoder = {
  379. "pam",
  380. CODEC_TYPE_VIDEO,
  381. CODEC_ID_PAM,
  382. sizeof(PNMContext),
  383. common_init,
  384. pam_encode_frame,
  385. NULL, //encode_end,
  386. pnm_decode_frame,
  387. .pix_fmts= (enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_GRAY8, PIX_FMT_MONOWHITE, -1},
  388. };
  389. #endif // CONFIG_PAM_ENCODER