jpegutils.c

来自「Motion JPEG编解码器源代码」· C语言 代码 · 共 1,145 行 · 第 1/3 页

C
1,145 行
字号
      0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,      0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,      0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,      0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,      0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,      0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,      0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,      0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,      0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,      0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,      0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,      0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,      0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,      0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,      0xf9, 0xfa };    add_huff_table(dinfo, &dinfo->dc_huff_tbl_ptrs[0],		 bits_dc_luminance, val_dc_luminance);  add_huff_table(dinfo, &dinfo->ac_huff_tbl_ptrs[0],		 bits_ac_luminance, val_ac_luminance);  add_huff_table(dinfo, &dinfo->dc_huff_tbl_ptrs[1],		 bits_dc_chrominance, val_dc_chrominance);  add_huff_table(dinfo, &dinfo->ac_huff_tbl_ptrs[1],		 bits_ac_chrominance, val_ac_chrominance);}static void guarantee_huff_tables(j_decompress_ptr dinfo){  if ( (dinfo->dc_huff_tbl_ptrs[0] == NULL) &&       (dinfo->dc_huff_tbl_ptrs[1] == NULL) &&       (dinfo->ac_huff_tbl_ptrs[0] == NULL) &&       (dinfo->ac_huff_tbl_ptrs[1] == NULL) ) {    mjpeg_debug( "Generating standard Huffman tables for this frame.");    std_huff_tables(dinfo);  }}#endif /* ...'std' Huffman table generation *//* * jpeg_data:       Buffer with jpeg data to decode * len:             Length of buffer * itype:           0: Not interlaced *                  1: Interlaced, Top field first *                  2: Interlaced, Bottom field first * ctype            Chroma format for decompression. *                  Currently only CHROMA420 and CHROMA422 are available */int decode_jpeg_raw (unsigned char *jpeg_data, int len,                     int itype, int ctype, int width, int height,                     unsigned char *raw0, unsigned char *raw1,                     unsigned char *raw2){   int numfields, hsf[3], vsf[3], field, yl, yc, x, y = 0, i, xsl, xsc, xs, xd,       hdown;   JSAMPROW row0[16] = { buf0[0], buf0[1], buf0[2], buf0[3],      buf0[4], buf0[5], buf0[6], buf0[7],      buf0[8], buf0[9], buf0[10], buf0[11],      buf0[12], buf0[13], buf0[14], buf0[15]   };   JSAMPROW row1[8] = { buf1[0], buf1[1], buf1[2], buf1[3],			buf1[4], buf1[5], buf1[6], buf1[7]   };   JSAMPROW row2[16] = { buf2[0], buf2[1], buf2[2], buf2[3],			 buf2[4], buf2[5], buf2[6], buf2[7]  };   JSAMPROW row1_444[16], row2_444[16];   JSAMPARRAY scanarray[3] = { row0, row1, row2 };   struct jpeg_decompress_struct dinfo;   struct my_error_mgr jerr;   /* We set up the normal JPEG error routines, then override error_exit. */   dinfo.err = jpeg_std_error (&jerr.pub);   jerr.pub.error_exit = my_error_exit;   /* Establish the setjmp return context for my_error_exit to use. */   if (setjmp (jerr.setjmp_buffer)) {      /* If we get here, the JPEG code has signaled an error. */      jpeg_destroy_decompress (&dinfo);      return -1;   }   jpeg_create_decompress (&dinfo);   jpeg_buffer_src (&dinfo, jpeg_data, len);   /* Read header, make some checks and try to figure out what the      user really wants */   jpeg_read_header (&dinfo, TRUE);   dinfo.raw_data_out = TRUE;   dinfo.out_color_space = JCS_YCbCr;   dinfo.dct_method = JDCT_IFAST;   guarantee_huff_tables(&dinfo);   jpeg_start_decompress (&dinfo);   if (dinfo.output_components != 3) {      mjpeg_error( "Output components of JPEG image = %d, must be 3",               dinfo.output_components);      goto ERR_EXIT;   }   for (i = 0; i < 3; i++) {      hsf[i] = dinfo.comp_info[i].h_samp_factor;      vsf[i] = dinfo.comp_info[i].v_samp_factor;   }   //mjpeg_info( "Sampling factors, hsf=(%d, %d, %d) vsf=(%d, %d, %d) !", hsf[0], hsf[1], hsf[2], vsf[0], vsf[1], vsf[2]);   if ((hsf[0] != 2 && hsf[0] != 1) || hsf[1] != 1 || hsf[2] != 1 ||       (vsf[0] != 1 && vsf[0] != 2) || vsf[1] != 1 || vsf[2] != 1) {      mjpeg_error( "Unsupported sampling factors, hsf=(%d, %d, %d) vsf=(%d, %d, %d) !", hsf[0], hsf[1], hsf[2], vsf[0], vsf[1], vsf[2]);      goto ERR_EXIT;   }   if (hsf[0] == 1)     {       if (height % 8 != 0)	 {	   mjpeg_error( "YUV 4:4:4 sampling, but image height %d not dividable by 8 !\n", height);	   goto ERR_EXIT;	   	 }       mjpeg_info("YUV 4:4:4 sampling encountered ! Allocating special row buffer\n");       for (y = 0; y < 16; y++) // allocate a special buffer for the extra sampling depth	 {	   //mjpeg_info("YUV 4:4:4 %d.\n",y);	   row1_444[y] = (unsigned char *)malloc(dinfo.output_width * sizeof(char));	   row2_444[y] = (unsigned char *)malloc(dinfo.output_width * sizeof(char));	 }       //mjpeg_info("YUV 4:4:4 sampling encountered ! Allocating done.\n");       scanarray[1] = row1_444;        scanarray[2] = row2_444;      }   /* Height match image height or be exact twice the image height */   if (dinfo.output_height == height) {      numfields = 1;   } else if (2 * dinfo.output_height == height) {      numfields = 2;   } else {      mjpeg_error(               "Read JPEG: requested height = %d, height of image = %d",               height, dinfo.output_height);      goto ERR_EXIT;   }   /* Width is more flexible */   if (dinfo.output_width > MAX_LUMA_WIDTH) {      mjpeg_error( "Image width of %d exceeds max",               dinfo.output_width);      goto ERR_EXIT;   }   if (width < 2 * dinfo.output_width / 3) {      /* Downsample 2:1 */      hdown = 1;      if (2 * width < dinfo.output_width)         xsl = (dinfo.output_width - 2 * width) / 2;      else         xsl = 0;   } else if (width == 2 * dinfo.output_width / 3) {      /* special case of 3:2 downsampling */      hdown = 2;      xsl = 0;   } else {      /* No downsampling */      hdown = 0;      if (width < dinfo.output_width)         xsl = (dinfo.output_width - width) / 2;      else         xsl = 0;   }   /* Make xsl even, calculate xsc */   xsl = xsl & ~1;   xsc = xsl / 2;   yl = yc = 0;   for (field = 0; field < numfields; field++) {      if (field > 0) {         jpeg_read_header (&dinfo, TRUE);         dinfo.raw_data_out = TRUE;         dinfo.out_color_space = JCS_YCbCr;         dinfo.dct_method = JDCT_IFAST;         jpeg_start_decompress (&dinfo);      }      if (numfields == 2) {         switch (itype) {         case LAV_INTER_TOP_FIRST:            yl = yc = field;            break;         case LAV_INTER_BOTTOM_FIRST:            yl = yc = (1 - field);            break;         default:            mjpeg_error(                     "Input is interlaced but no interlacing set");            goto ERR_EXIT;         }      } else         yl = yc = 0;      while (dinfo.output_scanline < dinfo.output_height) {	/* read raw data */	jpeg_read_raw_data (&dinfo, scanarray, 8 * vsf[0]);         for (y = 0; y < 8 * vsf[0]; yl += numfields, y++) {            xd = yl * width;            xs = xsl;            if (hdown == 0)               for (x = 0; x < width; x++)                  raw0[xd++] = row0[y][xs++];            else if (hdown == 1)               for (x = 0; x < width; x++, xs += 2)                  raw0[xd++] = (row0[y][xs] + row0[y][xs + 1]) >> 1;            else               for (x = 0; x < width / 2; x++, xd += 2, xs += 3) {                  raw0[xd] = (2 * row0[y][xs] + row0[y][xs + 1]) / 3;                  raw0[xd + 1] =                      (2 * row0[y][xs + 2] + row0[y][xs + 1]) / 3;               }         }	 /* Horizontal downsampling of chroma */         for (y = 0; y < 8; y++) {            xs = xsc;	    if (hsf[0] == 1)	      for (x = 0; x < width / 2; x++, xs++) 		{		  		  row1[y][xs] = (row1_444[y][2*x] + row1_444[y][2*x + 1]) >> 1;		  row2[y][xs] = (row2_444[y][2*x] + row2_444[y][2*x + 1]) >> 1;		}            xs = xsc;            if (hdown == 0)               for (x = 0; x < width / 2; x++, xs++) {		 chr1[y][x] = row1[y][xs];		 chr2[y][x] = row2[y][xs];            } else if (hdown == 1)               for (x = 0; x < width / 2; x++, xs += 2) {                  chr1[y][x] = (row1[y][xs] + row1[y][xs + 1]) >> 1;                  chr2[y][x] = (row2[y][xs] + row2[y][xs + 1]) >> 1;            } else               for (x = 0; x < width / 2; x += 2, xs += 3) {                  chr1[y][x] = (2 * row1[y][xs] + row1[y][xs + 1]) / 3;                  chr1[y][x + 1] =                      (2 * row1[y][xs + 2] + row1[y][xs + 1]) / 3;                  chr2[y][x] = (2 * row2[y][xs] + row2[y][xs + 1]) / 3;                  chr2[y][x + 1] =                      (2 * row2[y][xs + 2] + row2[y][xs + 1]) / 3;               }         }	 /* Vertical resampling of chroma */	 switch (ctype) {	 case CHROMA422:	   if (vsf[0] == 1) {	     /* Just copy */	     for (y = 0; y < 8 /*&& yc < height */; y++, yc += numfields) {	       xd = yc * width / 2;	       for (x = 0; x < width / 2; x++, xd++) {		 raw1[xd] = chr1[y][x];		 raw2[xd] = chr2[y][x];	       }	     }	   } else {	     /* upsample */	     for (y = 0; y < 8 /*&& yc < height */; y++) {	       xd = yc * width / 2;	       for (x = 0; x < width / 2; x++, xd++) {		 raw1[xd] = chr1[y][x];		 raw2[xd] = chr2[y][x];	       }	       yc += numfields;	       xd = yc * width / 2;	       for (x = 0; x < width / 2; x++, xd++) {		 raw1[xd] = chr1[y][x];		 raw2[xd] = chr2[y][x];	       }	       yc += numfields;	     }	   }	   break;	 default:	 /* should be case CHROMA420: but use default: for compatibility of liblavjpeg.so */	   if (vsf[0] == 1) {	     /* Really downsample */	     for (y = 0; y < 8 /*&& yc < height/2*/; y += 2, yc += numfields) {	       xd = yc * width / 2;	       for (x = 0; x < width / 2; x++, xd++) {		 assert(xd < (width * height / 4));		 raw1[xd] = (chr1[y][x] + chr1[y + 1][x]) >> 1;		 raw2[xd] = (chr2[y][x] + chr2[y + 1][x]) >> 1;	       }	     }	   } else {	     /* Just copy */	     for (y = 0; y < 8 /*&& yc < height/2 */; y++, yc += numfields) {	       xd = yc * width / 2;	       for (x = 0; x < width / 2; x++, xd++) {		 raw1[xd] = chr1[y][x];		 raw2[xd] = chr2[y][x];	       }	     }	   }	   break;	 }      }      (void) jpeg_finish_decompress (&dinfo);      if (field == 0 && numfields > 1)         jpeg_skip_ff (&dinfo);   }   if (hsf[0] == 1)     {       //mjpeg_info("YUV 4:4:4 sampling encountered ! Deallocating special row buffer\n");       for (y = 0; y < 16; y++) // allocate a special buffer for the extra sampling depth	 {	   free(row1_444[y]);	   free(row2_444[y]);	 }     }   jpeg_destroy_decompress (&dinfo);   return 0; ERR_EXIT:   jpeg_destroy_decompress (&dinfo);   return -1;}/* * jpeg_data:       Buffer with jpeg data to decode, must be grayscale mode * len:             Length of buffer * itype:           0: Not interlaced *                  1: Interlaced, Top field first *                  2: Interlaced, Bottom field first * ctype            Chroma format for decompression. *                  Currently only CHROMA420 and CHROMA422 are available */int decode_jpeg_gray_raw (unsigned char *jpeg_data, int len,			  int itype, int ctype, int width, int height,			  unsigned char *raw0, unsigned char *raw1,			  unsigned char *raw2){   int numfields, hsf[3], vsf[3], field, yl, yc, x, y, xsl, xsc, xs, xd,       hdown;   JSAMPROW row0[16] = { buf0[0], buf0[1], buf0[2], buf0[3],      buf0[4], buf0[5], buf0[6], buf0[7],      buf0[8], buf0[9], buf0[10], buf0[11],      buf0[12], buf0[13], buf0[14], buf0[15]   };   JSAMPARRAY scanarray[3] = { row0 };   struct jpeg_decompress_struct dinfo;   struct my_error_mgr jerr;   mjpeg_info("decoding jpeg gray\n");   /* We set up the normal JPEG error routines, then override error_exit. */   dinfo.err = jpeg_std_error (&jerr.pub);   jerr.pub.error_exit = my_error_exit;

⌨️ 快捷键说明

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