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 + -
显示快捷键?