⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pnmtoy4m.c

📁 Motion JPEG编解码器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  uint8_t *A = buffers[3];  for (y = 0; y < height; y++) {    pixels = rowbuffer;    y4m_read(fd, pixels, width * 4);    if (!bgra) {      for (x = 0; x < width; x++) {	*(R++) = *(pixels++);	*(G++) = *(pixels++);	*(B++) = *(pixels++);	*(A++) = *(pixels++);      }    } else {      for (x = 0; x < width; x++) {	*(B++) = *(pixels++);	*(G++) = *(pixels++);	*(R++) = *(pixels++);	*(A++) = *(pixels++);      }    }  }}staticvoid read_ppm_raw(int fd, uint8_t *buffers[],                  uint8_t *rowbuffer, int width, int height, int bgr) {  int x, y;  uint8_t *pixels;  uint8_t *R = buffers[0];  uint8_t *G = buffers[1];  uint8_t *B = buffers[2];  for (y = 0; y < height; y++) {    pixels = rowbuffer;    y4m_read(fd, pixels, width * 3);    if (!bgr) {      for (x = 0; x < width; x++) {	*(R++) = *(pixels++);	*(G++) = *(pixels++);	*(B++) = *(pixels++);      }    } else {      for (x = 0; x < width; x++) {	*(B++) = *(pixels++);	*(G++) = *(pixels++);	*(R++) = *(pixels++);      }    }  }}staticvoid read_pgm_raw(int fd, uint8_t *buffer, int width, int height) {  mjpeg_debug("read PGM into one buffer, %dx%d", width, height);  y4m_read(fd, buffer, width * height);}#define Y_BLACK 16#define Y_WHITE 219/*     000000000011111111112222222222     012345678901234567890123456789      76543210765432107654321076543210*/staticvoid read_pbm_raw(int fd, uint8_t *buffer, int width, int height) {  int row_bytes = (width + 7) >> 3;  int total_bytes = row_bytes * height;  uint8_t *pbm  = buffer + total_bytes - 1;  uint8_t *luma = buffer + (width * height) - 1;  int x, y;  mjpeg_debug("read PBM into one buffer, %dx%d", width, height);  y4m_read(fd, buffer, total_bytes);  for (y = height - 1; y >= 0; y--) {    for (x = width - 1; x >= 0; ) {      int shift = 7 - (x % 8);      uint8_t bits = *(pbm--) >> shift;      while (shift < 8) {        *(luma--) = (bits & 0x1) ? Y_BLACK : Y_WHITE;        bits >>= 1;        shift++;        x--;      }    }  }}staticvoid read_pnm_data(int fd, uint8_t *planes[],                   uint8_t *rowbuffer, pnm_info_t *pnm, int bgr){  switch (pnm->format) {  case FMT_PPM_RAW:    read_ppm_raw(fd, planes, rowbuffer, pnm->width, pnm->height, bgr);    break;  case FMT_PGM_RAW:    read_pgm_raw(fd, planes[0], pnm->width, pnm->height);    break;  case FMT_PBM_RAW:    read_pbm_raw(fd, planes[0], pnm->width, pnm->height);    break;  case FMT_PAM:    switch (pnm->tupl) {    case TUPL_RGB:      read_ppm_raw(fd, planes, rowbuffer, pnm->width, pnm->height, bgr);      break;    case TUPL_GRAY:      read_pgm_raw(fd, planes[0], pnm->width, pnm->height);      break;    case TUPL_RGB_ALPHA:      read_rgba_raw(fd, planes, rowbuffer, pnm->width, pnm->height, bgr);      break;    case TUPL_GRAY_ALPHA:    case TUPL_BW:    case TUPL_BW_ALPHA:    case TUPL_UNKNOWN:      mjpeg_error_exit1("Unknown/unhandled PAM tuple/format.");      break;    }    break;  case FMT_PBM_PLAIN:  case FMT_PGM_PLAIN:  case FMT_PPM_PLAIN:  case FMT_UNKNOWN:    mjpeg_error_exit1("Unknown/unhandled PNM format.");    break;  }}/*  * Read one whole frame. * * If non-interleaved fields, this requires reading two PNM images. * */staticint read_pnm_frame(int fd, pnm_info_t *pnm,		   uint8_t *buffers[], uint8_t *buffers2[],		   int de_leaved, int bgr){  static uint8_t *rowbuffer = NULL;  pnm_info_t new_pnm;  int err;  err = read_pnm_header(fd, &new_pnm); //&format, &width, &height);  if (err > 0) return 1;  /* EOF */  if (err < 0) return -1; /* error */  mjpeg_debug("Got PNM header:  [%s%s%s] %dx%d",              magics[new_pnm.format],              (new_pnm.format == FMT_PAM) ? " " : "",              (new_pnm.format == FMT_PAM) ? tupls[new_pnm.tupl].tag : "",              new_pnm.width, new_pnm.height);  if (pnm->width == 0) { /* first time */    mjpeg_debug("Initializing PNM read_frame");    pnm_info_copy(pnm, &new_pnm);    rowbuffer = malloc(new_pnm.width * new_pnm.depth * sizeof(rowbuffer[0]));  } else {    /* make sure everything matches */    if ( !pnm_info_equal(pnm, &new_pnm) )      mjpeg_error_exit1("One of these frames is not like the others!");  }  if (buffers[0] == NULL)     alloc_buffers(buffers, new_pnm.width, new_pnm.height, new_pnm.depth);  if ((buffers2[0] == NULL) && (de_leaved))    alloc_buffers(buffers2, new_pnm.width, new_pnm.height, new_pnm.depth);  /* Interleaved or not --> read image into first buffer... */  read_pnm_data(fd, buffers, rowbuffer, pnm, bgr);  if (de_leaved) {    /* Really Non-Interleaved:  --> read second field into second buffer */    err = read_pnm_header(fd, &new_pnm); //&format, &width, &height);    if (err > 0) return 1;  /* EOF */    if (err < 0) return -1; /* error */    mjpeg_debug("Got second PNM header:  [%s] %dx%d",                magics[new_pnm.format], new_pnm.width, new_pnm.height);    /* make sure everything matches */    if ( !pnm_info_equal(pnm, &new_pnm) )      mjpeg_error_exit1("One of these fields is not like the others!");    read_pnm_data(fd, buffers2, rowbuffer, pnm, bgr);  }  return 0;}staticvoid setup_output_stream(int fdout, cl_info_t *cl,			 y4m_stream_info_t *sinfo, pnm_info_t *pnm,			 int *field_height) {  int err;  int ss_mode = Y4M_UNKNOWN;  if ( (cl->output_interlace != Y4M_ILACE_NONE) &&       (!cl->deinterleave) &&       ((pnm->height % 2) != 0) )    mjpeg_error_exit1("Frame height (%d) is not a multiple of 2!",                      pnm->height);  y4m_si_set_width(sinfo, pnm->width);  if (cl->deinterleave)    y4m_si_set_height(sinfo, pnm->height * 2);  else     y4m_si_set_height(sinfo, pnm->height);    y4m_si_set_sampleaspect(sinfo, cl->output_aspect);  y4m_si_set_interlace(sinfo, cl->output_interlace);  y4m_si_set_framerate(sinfo, cl->output_framerate);  switch (pnm->format) {  case FMT_PPM_RAW:  case FMT_PPM_PLAIN:    ss_mode = Y4M_CHROMA_444;  break;  case FMT_PGM_RAW:  case FMT_PGM_PLAIN:  case FMT_PBM_RAW:  case FMT_PBM_PLAIN:    ss_mode = Y4M_CHROMA_MONO; break;  case FMT_PAM:    switch (pnm->tupl) {    case TUPL_RGB:      ss_mode = Y4M_CHROMA_444;       break;    case TUPL_GRAY:      ss_mode = Y4M_CHROMA_MONO;      break;    case TUPL_RGB_ALPHA:      ss_mode = Y4M_CHROMA_444ALPHA;  break;    case TUPL_GRAY_ALPHA:    case TUPL_BW:    case TUPL_BW_ALPHA:    case TUPL_UNKNOWN:      assert(0);      break;    }    break;  case FMT_UNKNOWN:    assert(0);    break;  }  y4m_si_set_chroma(sinfo, ss_mode);  if ((err = y4m_write_stream_header(fdout, sinfo)) != Y4M_OK)    mjpeg_error_exit1("Write header failed:  %s", y4m_strerr(err));  mjpeg_info("Output Stream parameters:");  y4m_log_stream_info(LOG_INFO, "  ", sinfo);}int main(int argc, char **argv){  cl_info_t cl;  y4m_stream_info_t sinfo;  y4m_frame_info_t finfo;  uint8_t *planes[Y4M_MAX_NUM_PLANES];  /* R'G'B' or Y'CbCr */  uint8_t *planes2[Y4M_MAX_NUM_PLANES]; /* R'G'B' or Y'CbCr */  pnm_info_t pnm;  int field_height;  int fdout = 1; /* stdout */  int err, i, count, repeating_last;  y4m_accept_extensions(1);  y4m_init_stream_info(&sinfo);  y4m_init_frame_info(&finfo);  parse_args(&cl, argc, argv);  pnm.width = 0;  pnm.height = 0;  for (i = 0; i < Y4M_MAX_NUM_PLANES; i++) {    planes[i] = NULL;    planes2[i] = NULL;  }  /* Read first PPM frame/field-pair, to get dimensions/format. */  if (read_pnm_frame(cl.fdin, &pnm, planes, planes2, cl.deinterleave, cl.bgr))    mjpeg_error_exit1("Failed to read first frame.");  /* Setup streaminfo and write output header */  setup_output_stream(fdout, &cl, &sinfo, &pnm, &field_height);  /* Loop 'framecount' times, or possibly forever... */  for (count = 0, repeating_last = 0;       (count < (cl.offset + cl.framecount)) || (cl.framecount == 0);       count++) {    if (repeating_last) goto WRITE_FRAME;    /* Read PPM frame/field */    /* ...but skip reading very first frame, already read prior to loop */    if (count > 0) {      err = read_pnm_frame(cl.fdin, &pnm, planes, planes2, cl.deinterleave, cl.bgr);      if (err == 1) {	/* clean input EOF */	if (cl.repeatlast) {	  repeating_last = 1;	  goto WRITE_FRAME;	} else if (cl.framecount != 0) {	  mjpeg_error_exit1("Input frame shortfall (only %d converted).",			    count - cl.offset);	} else {	  break;  /* input is exhausted; we are done!  time to go home! */	}      } else if (err)	mjpeg_error_exit1("Error reading pnm frame");    }        /* ...skip transforms if we are just going to skip this frame anyway.       BUT, if 'cl.repeatlast' is on, we must process/buffer every frame,       because we don't know when we will see the last one. */    if ((count >= cl.offset) || (cl.repeatlast)) {      /* Transform colorspace. */      switch (pnm.format) {      case FMT_PPM_PLAIN:      case FMT_PPM_RAW:        convert_RGB_to_YCbCr(planes, pnm.width * pnm.height);        if (cl.deinterleave)          convert_RGB_to_YCbCr(planes2, pnm.width * pnm.height);        break;      case FMT_PGM_PLAIN:      case FMT_PGM_RAW:        convert_Y255_to_Y219(planes[0], pnm.width * pnm.height);        if (cl.deinterleave)          convert_Y255_to_Y219(planes2[0], pnm.width * pnm.height);        break;      case FMT_PBM_PLAIN:      case FMT_PBM_RAW:        /* all set.  (converted at read time) */        break;      case FMT_PAM:        switch (pnm.tupl) {        case TUPL_RGB:          convert_RGB_to_YCbCr(planes, pnm.width * pnm.height);          if (cl.deinterleave)            convert_RGB_to_YCbCr(planes2, pnm.width * pnm.height);          break;        case TUPL_GRAY:          convert_Y255_to_Y219(planes[0], pnm.width * pnm.height);          if (cl.deinterleave)            convert_Y255_to_Y219(planes2[0], pnm.width * pnm.height);          break;        case TUPL_RGB_ALPHA:          convert_RGB_to_YCbCr(planes, pnm.width * pnm.height);          convert_Y255_to_Y219(planes[3], pnm.width * pnm.height);          if (cl.deinterleave) {            convert_RGB_to_YCbCr(planes2, pnm.width * pnm.height);            convert_Y255_to_Y219(planes2[3], pnm.width * pnm.height);          }          break;        case TUPL_GRAY_ALPHA:        case TUPL_BW:        case TUPL_BW_ALPHA:        case TUPL_UNKNOWN:          assert(0);          break;        }        break;      case FMT_UNKNOWN:        assert(0);        break;      }    }  WRITE_FRAME:    /* Write converted frame to output */    if (count >= cl.offset) {      if (cl.deinterleave) {        switch (cl.input_interlace) {        case Y4M_ILACE_TOP_FIRST:          err = y4m_write_fields(fdout, &sinfo, &finfo, planes, planes2);          break;        case Y4M_ILACE_BOTTOM_FIRST:          err = y4m_write_fields(fdout, &sinfo, &finfo, planes2, planes);          break;        case Y4M_ILACE_NONE:        default:          assert(0);          break;        }      } else {	err = y4m_write_frame(fdout, &sinfo, &finfo, planes);      }      if (err != Y4M_OK)        mjpeg_error_exit1("Write frame/fields failed: %s", y4m_strerr(err));    }  }   for (i = 0; i < Y4M_MAX_NUM_PLANES; i++) {    if (planes[i] != NULL)  free(planes[i]);    if (planes2[i] != NULL) free(planes2[i]);  }  y4m_fini_stream_info(&sinfo);  y4m_fini_frame_info(&finfo);  mjpeg_debug("Done.");  return 0;}#if 0staticvoid read_two_ppm_raw(int fd,                      uint8_t *buffers[], uint8_t *buffers2[],                       uint8_t *rowbuffer, int width, int height, int bgr){  int x, y;  uint8_t *pixels;  uint8_t *R = buffers[0];  uint8_t *G = buffers[1];  uint8_t *B = buffers[2];  uint8_t *R2 = buffers2[0];  uint8_t *G2 = buffers2[1];  uint8_t *B2 = buffers2[2];  mjpeg_debug("read into two buffers, %dx%d", width, height);  height /= 2;  for (y = 0; y < height; y++) {    pixels = rowbuffer;    if (y4m_read(fd, pixels, width * 3))      mjpeg_error_exit1("read error A  y=%d", y);    if (!bgr) {      for (x = 0; x < width; x++) {	*(R++) = *(pixels++);	*(G++) = *(pixels++);	*(B++) = *(pixels++);      }    } else {      for (x = 0; x < width; x++) {	*(B++) = *(pixels++);	*(G++) = *(pixels++);	*(R++) = *(pixels++);      }    }    pixels = rowbuffer;    if (y4m_read(fd, pixels, width * 3))      mjpeg_error_exit1("read error B  y=%d", y);    if (!bgr) {      for (x = 0; x < width; x++) {	*(R2++) = *(pixels++);	*(G2++) = *(pixels++);	*(B2++) = *(pixels++);      }    } else {      for (x = 0; x < width; x++) {	*(B2++) = *(pixels++);	*(G2++) = *(pixels++);	*(R2++) = *(pixels++);      }    }  }}staticvoid read_two_pgm_raw(int fd,                      uint8_t *buffer, uint8_t *buffer2,                       int width, int height){  int y;  mjpeg_debug("read PGM into two buffers, %dx%d", width, height);  for (y = 0; y < height; y += 2) {    if (y4m_read(fd, buffer, width))      mjpeg_error_exit1("read error A  y=%d", y);    buffer += width;    if (y4m_read(fd, buffer2, width))      mjpeg_error_exit1("read error B  y=%d", y);    buffer2 += width;  }}staticvoid read_pnm_into_two_buffers(int fd,                               uint8_t *planes[],                               uint8_t *planes2[],                               uint8_t *rowbuffer,                               pnm_info_t *pnm, int bgr){  switch (pnm->format) {  case FMT_PPM_RAW:    read_two_ppm_raw(fd, planes, planes2, rowbuffer, pnm->width, pnm->height, bgr);    break;  case FMT_PGM_RAW:    read_two_pgm_raw(fd, planes[0], planes2[0], pnm->width, pnm->height);    break;  case FMT_PBM_RAW:    //    read_two_pbm_raw(fd, planes[0], planes2[0], pnm->width, pnm->height);    break;  case FMT_PBM_PLAIN:  case FMT_PGM_PLAIN:  case FMT_PPM_PLAIN:  case FMT_UNKNOWN:    assert(0);    break;  }}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -