📄 jpeg.c
字号:
* * ReadJPEG contributed by James Arthur Boucher of Boston University's * Multimedia Communications Lab * * read a JPEG file and copy data into frame original data arrays * * RETURNS: mf modified * * SIDE EFFECTS: none * *===========================================================================*//*************************JPEG LIBRARY INTERFACE*********************//* * THE BIG PICTURE: * * The rough outline this JPEG decompression operation is: * * allocate and initialize JPEG decompression object * specify data source (eg, a file) * jpeg_read_header(); // obtain image dimensions and other parameters * set parameters for decompression * jpeg_start_decompress(); * while (scan lines remain to be read) * jpeg_read_scanlines(...); * jpeg_finish_decompress(); * release JPEG decompression object * */voidReadJPEG(mf, fp) MpegFrame *mf; FILE *fp;{ /* This struct contains the JPEG decompression parameters and pointers to * working data (which is allocated as needed by the JPEG library). */ static struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; /* More stuff */ JSAMPARRAY scanarray[3]; int ci,cd,cp; JDIMENSION ncols[3]; JDIMENSION nrows[3]; jpeg_component_info *compptr; int buffer_height; int current_row[3]; uint8 **orig[3]; int h_samp[3],v_samp[3]; int max_h_samp,max_v_samp; int temp_h, temp_v; int temp; /* Allocate and initialize JPEG decompression object */ cinfo.err = jpeg_std_error(&jerr); /* ** If we're reading from stdin we want to create the cinfo struct ** ONCE (during the first read). This is because when reading jpeg ** from stdin we will not release the cinfo struct, because doing ** so would totally screw up the read buffer and make it impossible ** to read jpegs from stdin. ** Dave Scott (dhs), UofO, 7/19/95 */ { static int first_stdin = 1; if( (fp != stdin) || first_stdin) { first_stdin = 0; /* Now we can initialize the JPEG decompression object. */ jpeg_create_decompress(&cinfo); /* specify data source (eg, a file) */ jpeg_stdio_src(&cinfo, fp); } } /* specify data source (eg, a file) */ jpeg_stdio_src(&cinfo, fp); /* read file parameters with jpeg_read_header() */ (void) jpeg_read_header(&cinfo, TRUE); /* We can ignore the return value from jpeg_read_header since * (a) suspension is not possible with the stdio data source, and * (b) we passed TRUE to reject a tables-only JPEG file as an error. */ /* set parameters for decompression */#ifdef JPEG4 cinfo.want_raw_output = TRUE;#else cinfo.raw_data_out = TRUE;#endif cinfo.out_color_space = JCS_YCbCr; /* calculate image output dimensions */ jpeg_calc_output_dimensions(&cinfo); /* the above calculation will set these soon */ /* for now we'll set them ourselves */ /* tell mpeg_encode the size of the JPEG Image*/ Fsize_Note(mf->id,(int)(cinfo.image_width),(int)(cinfo.image_height)); /* Allocate memory for the raw YCbCr data to occupy*/ Frame_AllocYCC(mf); /*allocate space for mpeg frame*/ /* copy pointers to array structure- this make the following code more compact */ orig[0] = mf->orig_y; orig[1] = mf->orig_cb; orig[2] = mf->orig_cr; /* Note that we can use the info obtained from jpeg_read_header. */ /* Start decompressor */ jpeg_start_decompress(&cinfo); /* JSAMPLEs per row in output buffer */ /* collect component subsample values*/ for(cp=0,compptr = cinfo.comp_info;cp<cinfo.num_components; cp++,compptr++) { h_samp[cp] = compptr->h_samp_factor; v_samp[cp] = compptr->v_samp_factor; } /* calculate max subsample values*/ temp_h = (h_samp[0]<h_samp[1]) ? h_samp[1] : h_samp[0]; max_h_samp = (temp_h<h_samp[2]) ? h_samp[2]:temp_h; temp_v = (v_samp[0]<v_samp[1]) ? v_samp[1] : v_samp[0]; max_v_samp = (temp_v<v_samp[2]) ? v_samp[2]:temp_v; /* Make an 8-row-high sample array that will go away when done with image */#ifdef JPEG4 buffer_height = 8; /* could be 2, 4,8 rows high */#else buffer_height = cinfo.max_v_samp_factor * cinfo.min_DCT_scaled_size;#endif for(cp=0,compptr = cinfo.comp_info;cp<cinfo.num_components; cp++,compptr++) { ncols[cp] = (JDIMENSION)((cinfo.image_width*compptr->h_samp_factor)/ max_h_samp); nrows[cp] = (JDIMENSION)((buffer_height*compptr->v_samp_factor)/ max_v_samp); scanarray[cp] = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, ncols[cp], nrows[cp]); } /* while (scan lines remain to be read) */ /* jpeg_read_scanlines(...); */ /* Here we use the library's state variable cinfo.output_scanline as the * loop counter, so that we don't have to keep track ourselves. */ while (cinfo.output_scanline < cinfo.output_height) {#ifdef JPEG4 (void) jpeg_read_raw_scanlines(&cinfo, scanarray, buffer_height);#else (void) jpeg_read_raw_data(&cinfo, scanarray, buffer_height);#endif/* alter subsample ratio's if neccessary */ if((h_samp[0]==2)&&(h_samp[1]==1)&&(h_samp[2]==1)&& (v_samp[0]==2)&&(v_samp[1]==1)&&(v_samp[2]==1)){ /* we are 4:1:1 as expected by the encoder*/ }else if((h_samp[0]==2)&&(h_samp[1]==1)&&(h_samp[2]==1)&& (v_samp[0]==1)&&(v_samp[1]==1)&&(v_samp[2]==1)){ /* must subsample 2:1 vertically and adjust params*/ for(ci=1; ci<3; ci++){ for(cp=0; cp<(buffer_height/2);cp=cp+1){ for(cd=0;cd<ncols[ci];cd++){ temp =((scanarray[ci][cp*2][cd]+scanarray[ci][(cp*2)+1][cd])/2); scanarray[ci][cp][cd] = (JSAMPLE)(temp); } } } /* only reset values the first time through*/ if(cinfo.output_scanline==buffer_height){ nrows[1] = nrows[1]/2; nrows[2] = nrows[2]/2; max_v_samp = 2; v_samp[0] = 2; } }else{ fprintf(stderr, "Not a supported subsampling ratio\n"); exit(1); } /* transfer data from jpeg buffer to MPEG frame */ /* calculate the row we wish to output into */ for(ci=0,compptr=cinfo.comp_info; ci<cinfo.num_components; ci++,compptr++){ current_row[ci] =((cinfo.output_scanline - buffer_height)* (v_samp[ci])/max_v_samp); jcopy_sample_rows(scanarray[ci],0,(JSAMPARRAY)(orig[ci]), current_row[ci],nrows[ci],ncols[ci]); } } /* Step 7: Finish decompression */ (void) jpeg_finish_decompress(&cinfo); /* We can ignore the return value since suspension is not possible * with the stdio data source. */ /* Step 8: Release JPEG decompression object */ /* ** DO NOT release the cinfo struct if we are reading from stdin, this ** is because the cinfo struct contains the read buffer, and the read ** buffer may (and almost always does) contain the end of one image and ** the beginning of another. If we throw away the read buffer then ** we loose the beginning of the next image, and we're screwed. ** Dave Scott (dhs), UofO, 7/19/95 */ if( fp == stdin) { static int no_from_stdin = 0; no_from_stdin++; /* fprintf( stderr, "%d jpeg images read from stdin\n", no_from_stdin); */ } else { /* This is an important step since it will release a good deal of memory. */ jpeg_destroy_decompress(&cinfo); } /* After finish_decompress, we can close the input file. * Here we postpone it until after no more JPEG errors are possible, * so as to simplify the setjmp error logic above. (Actually, I don't * think that jpeg_destroy can do an error exit, but why assume anything...) */ /* At this point you may want to check to see whether any corrupt-data * warnings occurred (test whether jerr.pub.num_warnings is nonzero). * If you prefer to treat corrupt data as a fatal error, override the * error handler's emit_message method to call error_exit on a warning. */ /* And we're done! */ }/* * SOME FINE POINTS: * * In the above loop, we ignored the return value of jpeg_read_scanlines, * which is the number of scanlines actually read. We could get away with * this for the same reasons discussed in the compression example. Actually * there is one perfectly normal situation in which jpeg_read_scanlines may * return fewer lines than you asked for: at the bottom of the image. But the * loop above can't ask for more lines than there are in the image since it * reads only one line at a time. * * In some high-speed operating modes, some data copying can be saved by * making the buffer passed to jpeg_read_scanlines be cinfo.rec_outbuf_height * lines high (or a multiple thereof). This will usually be 1, 2, or 4 lines. * * To decompress multiple images, you can repeat the whole sequence, or you * can keep the JPEG object around and just repeat steps 2-7. This will * save a little bit of startup/shutdown time. * * As with compression, some operating modes may require temporary files. * On some systems you may need to set up a signal handler to ensure that * temporary files are deleted if the program is interrupted. * * Scanlines are returned in the same order as they appear in the JPEG file, * which is standardly top-to-bottom. If you must have data supplied * bottom-to-top, you can use one of the virtual arrays provided by the * JPEG memory manager to invert the data. See wrrle.c for an example. *//* * Copyright (c) 1995 The Regents of the University of California. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice and the following * two paragraphs appear in all copies of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. *//* * 00.03.30 Bryan changed "jpeglib.h" to <jpeglib.h> to make it work with * newer jpeg library. * * $Header: /u/smoot/md/mpeg_encode/RCS/jpeg.c,v 1.6 1995/06/08 20:36:00 smoot Exp $ * $Log: jpeg.c,v $ * Revision 1.6 1995/06/08 20:36:00 smoot * added "b"'s to fopen()s for MSDOS * * Revision 1.5 1995/02/02 21:24:02 eyhung * slight cleanup of unused variables * * Revision 1.4 1995/01/19 23:08:33 eyhung * Changed copyrights * * Revision 1.3 1995/01/19 22:58:34 smoot * fixes (I dont know what) * * Revision 1.2 1994/11/12 02:11:50 keving * nothing * * Revision 1.1 1994/03/15 00:27:11 keving * nothing * * Revision 1.2 1993/12/22 19:19:01 keving * nothing * * Revision 1.1 1993/07/22 22:23:43 keving * nothing * */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -