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

📄 jpeg2yuv.c

📁 实现JPEG与YUV图像格式的转换
💻 C
📖 第 1 页 / 共 2 页
字号:
  		      dinfo.output_components);

  if (dinfo.output_components != 1 && dinfo.out_color_space == JCS_GRAYSCALE)
    mjpeg_error_exit1("Output components of grayscale JPEG image = %d, must be 1.",
  		      dinfo.output_components);
  
  mjpeg_info("Image dimensions are %dx%d",
	     dinfo.image_width, dinfo.image_height);
  /* picture size check  */
  if ( (dinfo.image_width % 2) != 0 )
    mjpeg_error_exit1("The image width has to be a even number, rescale the image");
  if ( (dinfo.image_height % 2) != 0 )
    mjpeg_error_exit1("The image height has to be even number, rescale the image");

  param->width = dinfo.image_width;
  param->height = dinfo.image_height;
  param->colorspace = dinfo.jpeg_color_space;
  
  jpeg_destroy_decompress(&dinfo);
  fclose(jpegfile);

  mjpeg_info("Movie frame rate is:  %f frames/second",
	     Y4M_RATIO_DBL(param->framerate));

  switch (param->interlace) {
  case Y4M_ILACE_NONE:
    mjpeg_info("Non-interlaced/progressive frames.");
    break;
  case Y4M_ILACE_BOTTOM_FIRST:
    mjpeg_info("Interlaced frames, bottom field first.");      
    break;
  case Y4M_ILACE_TOP_FIRST:
    mjpeg_info("Interlaced frames, top field first.");      
    break;
  default:
    mjpeg_error_exit1("Interlace has not been specified (use -I option)");
    break;
  }

  if ((param->interlace != Y4M_ILACE_NONE) && (param->interleave == -1))
    mjpeg_error_exit1("Interleave has not been specified (use -L option)");

  if (!(param->interleave) && (param->interlace != Y4M_ILACE_NONE)) {
    param->height *= 2;
    mjpeg_info("Non-interleaved fields (image height doubled)");
  }
  mjpeg_info("Frame size:  %d x %d", param->width, param->height);

  return 0;
}

/**
  Rescales the YUV values from the range 0..255 to the range 16..235 
  @param yp: buffer for Y plane of decoded JPEG 
  @param up: buffer for U plane of decoded JPEG 
  @param vp: buffer for V plane of decoded JPEG 
*/
static void rescale_color_vals(int width, int height, uint8_t *yp, uint8_t *up, uint8_t *vp) 
{
  int x,y;
  for (y = 0; y < height; y++)
    for (x = 0; x < width; x++)
      yp[x+y*width] = (float)(yp[x+y*width])/255.0 * (235.0 - 16.0) + 16.0;

  for (y = 0; y < height/2; y++)
    for (x = 0; x < width/2; x++)
      {
	up[x+y*width/2] = (float)(up[x+y*width/2])/255.0 * (240.0 - 16.0) + 16.0;
	vp[x+y*width/2] = (float)(vp[x+y*width/2])/255.0 * (240.0 - 16.0) + 16.0;
      }
}

static int generate_YUV4MPEG(parameters_t *param)
{
  uint32_t frame;
  size_t jpegsize;
  char jpegname[FILENAME_MAX];
  FILE *jpegfile;
  int loops;                                 /* number of loops to go */
  uint8_t *yuv[3];  /* buffer for Y/U/V planes of decoded JPEG */
  static uint8_t jpegdata[MAXPIXELS];  /* that ought to be enough */
  y4m_stream_info_t streaminfo;
  y4m_frame_info_t frameinfo;
  loops = param->loop;
  DIR *dirp;
  struct dirent *dp;

  yuv[0] = yuv[1] 
	 = yuv[2] 
	 = NULL;

  mjpeg_info("Number of Loops %i", loops);

  mjpeg_info("Now generating YUV4MPEG stream.");

  dirp = opendir(param->jpegformatstr);
  if (dirp == NULL) {
           mjpeg_info("Could not open input directory.");
	   return 1;
  } else {
           mjpeg_info("Opening input directory.");
  }
 
     while ((dp = readdir(dirp)) != NULL)
     {
	sprintf(jpegname, "%s%s", param->jpegformatstr, dp->d_name);

	if (!strstr(dp->d_name, ".jpg") && !strstr(dp->d_name, ".JPG") && !strstr(dp->d_name, ".jpeg") && !strstr(dp->d_name, ".JPEG"))
		continue;

	if (init_parse_files(param, jpegname))
		continue;

	y4m_init_stream_info(&streaminfo);
	y4m_init_frame_info(&frameinfo);

	y4m_si_set_width(&streaminfo, param->width);
	y4m_si_set_height(&streaminfo, param->height);
	y4m_si_set_interlace(&streaminfo, param->interlace);
	y4m_si_set_framerate(&streaminfo, param->framerate);

	yuv[0] = realloc(yuv[0], param->width * param->height * sizeof(yuv[0][0]));
	yuv[1] = realloc(yuv[1], param->width * param->height / 4 * sizeof(yuv[1][0]));
	yuv[2] = realloc(yuv[2], param->width * param->height / 4 * sizeof(yuv[2][0]));

	y4m_write_stream_header(STDOUT_FILENO, &streaminfo);

   
//       snprintf(jpegname, sizeof(jpegname), param->jpegformatstr, frame);
       jpegfile = fopen(jpegname, "rb");
       
       if (jpegfile == NULL) { 
         mjpeg_info("Read from '%s' failed:  %s", dp->d_name, strerror(errno));
         if (param->numframes == -1) {
           mjpeg_info("No more frames.  Stopping.");
           break;  /* we are done; leave 'while' loop */
         } else {
           mjpeg_info("Rewriting latest frame instead.");
         }
       } else {
         mjpeg_debug("Preparing frame");
         
         jpegsize = fread(jpegdata, sizeof(unsigned char), MAXPIXELS, jpegfile); 
         fclose(jpegfile);
         
         /* decode_jpeg_raw:s parameters from 20010826
          * jpeg_data:       buffer with input / output jpeg
          * len:             Length of jpeg buffer
          * itype:           0: Interleaved/Progressive
          *                  1: Not-interleaved, Top field first
          *                  2: Not-interleaved, Bottom field first
          * ctype            Chroma format for decompression.
          *                  Currently always 420 and hence ignored.
          * raw0             buffer with input / output raw Y channel
          * raw1             buffer with input / output raw U/Cb channel
          * raw2             buffer with input / output raw V/Cr channel
          * width            width of Y channel (width of U/V is width/2)
          * height           height of Y channel (height of U/V is height/2)
          */
   
         if ((param->interlace == Y4M_ILACE_NONE) || (param->interleave == 1)) {
           mjpeg_info("Processing non-interlaced/interleaved %s, size %ul.", 
                      dp->d_name, jpegsize);
	   if (param->colorspace == JCS_GRAYSCALE)
	       decode_jpeg_gray_raw(jpegdata, jpegsize,
				    0, 420, param->width, param->height,
				    yuv[0], yuv[1], yuv[2]);
	   else
	     decode_jpeg_raw(jpegdata, jpegsize,
			     0, 420, param->width, param->height,
			     yuv[0], yuv[1], yuv[2]);
         } else {
           switch (param->interlace) {
           case Y4M_ILACE_TOP_FIRST:
             mjpeg_info("Processing interlaced, top-first %s, size %ul.",
                        jpegname, jpegsize);
	     if (param->colorspace == JCS_GRAYSCALE)
	       decode_jpeg_gray_raw(jpegdata, jpegsize,
				    LAV_INTER_TOP_FIRST, 
				    420, param->width, param->height,
				    yuv[0], yuv[1], yuv[2]);
	     else
	       decode_jpeg_raw(jpegdata, jpegsize,
			       LAV_INTER_TOP_FIRST,
			       420, param->width, param->height,
			       yuv[0], yuv[1], yuv[2]);
             break;
           case Y4M_ILACE_BOTTOM_FIRST:
             mjpeg_info("Processing interlaced, bottom-first %s, size %ul.", 
                        jpegname, jpegsize);
	     if (param->colorspace == JCS_GRAYSCALE)
	       decode_jpeg_gray_raw(jpegdata, jpegsize,
				    LAV_INTER_BOTTOM_FIRST, 
				    420, param->width, param->height,
				    yuv[0], yuv[1], yuv[2]);
	     else
	       decode_jpeg_raw(jpegdata, jpegsize,
			       LAV_INTER_BOTTOM_FIRST,
			       420, param->width, param->height,
			       yuv[0], yuv[1], yuv[2]);
             break;
           default:
             mjpeg_error_exit1("FATAL logic error?!?");
             break;
           }
         }

	 if (param->rescale_YUV)
	   {
	     mjpeg_info("Rescaling color values.");
	     rescale_color_vals(param->width, param->height, yuv[0], yuv[1], yuv[2]);
	   }
	 mjpeg_debug("Frame decoded, now writing to output stream.");
       }
   
  loops = param->loop;
  do { /* while */
       y4m_write_frame(STDOUT_FILENO, &streaminfo, &frameinfo, yuv);
     if (param->loop != -1)
       loops--;
 
  } while( loops >=1 || loops == -1 );

  } /* while */
  
  y4m_fini_stream_info(&streaminfo);
  y4m_fini_frame_info(&frameinfo);

  closedir(dirp);

  free(yuv[0]);
  free(yuv[1]);
  free(yuv[2]);

  return 0;
}

⌨️ 快捷键说明

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