📄 readframe.c
字号:
/* Make an 8-row-high sample array that will go away when done with image */ buffer_height = 8; /* could be 2, 4,8 rows high */ 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) { (void) jpeg_read_raw_scanlines(&cinfo, scanarray, buffer_height);/* 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 */ /* 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. *//*===========================================================================* * * ReadPNM * * read a PNM file * * RETURNS: mf modified * * SIDE EFFECTS: none * *===========================================================================*/static voidReadPNM(fp, mf) FILE *fp; MpegFrame *mf;{ int x, y; xelval maxval; int format; mf->rgb_data = pnm_readpnm(fp, &x, &y, &maxval, &format); ERRCHK(mf, "pnm_readpnm"); if (format != PPM_FORMAT) { if (maxval < 255) { pnm_promoteformat(mf->rgb_data, x, y, maxval, format, 255, PPM_FORMAT); maxval = 255; } else { pnm_promoteformat(mf->rgb_data, x, y, maxval, format, maxval, PPM_FORMAT); } } if (maxval < 255) { pnm_promoteformat(mf->rgb_data, x, y, maxval, format, 255, format); maxval = 255; } /* * if this is the first frame read, set the global frame size */ Fsize_Note(mf->id, x, y); mf->rgb_maxval = maxval; mf->rgb_format = PPM_FORMAT;}/*===========================================================================* * * ReadIOConvert * * do conversion; return a pointer to the appropriate file * * RETURNS: pointer to the appropriate file * * SIDE EFFECTS: none * *===========================================================================*/FILE *ReadIOConvert(fileName) char *fileName;{ FILE *ifp; char command[1024]; char fullFileName[1024]; char *convertPtr, *commandPtr, *charPtr; sprintf(fullFileName, "%s/%s", currentPath, fileName);#ifdef BLEAH if ( ! childProcess ) { fprintf(stdout, "+++++READING (IO CONVERT) Frame %d (type %d): %s\n", frame->id, frame->type, fullFileName); }#endif if ( strcmp(ioConversion, "*") == 0 ) { ifp = fopen(fullFileName, "r"); ERRCHK(ifp, "fopen"); return ifp; } /* replace every occurrence of '*' with fullFileName */ convertPtr = ioConversion; commandPtr = command; while ( *convertPtr != '\0' ) { while ( (*convertPtr != '\0') && (*convertPtr != '*') ) { *commandPtr = *convertPtr; commandPtr++; convertPtr++; } if ( *convertPtr == '*' ) { /* copy fullFileName */ charPtr = fullFileName; while ( *charPtr != '\0' ) { *commandPtr = *charPtr; commandPtr++; charPtr++; } convertPtr++; /* go past '*' */ } } *commandPtr = '\0'; if ( (ifp = popen(command, "r")) == NULL ) { fprintf(stderr, "ERROR: Couldn't execute input conversion command:\n"); fprintf(stderr, "\t%s\n", command); fprintf(stderr, "errno = %d\n", errno); if ( ioServer ) { fprintf(stderr, "IO SERVER: EXITING!!!\n"); } else { fprintf(stderr, "SLAVE EXITING!!!\n"); } exit(1); } return ifp;}/*===========================================================================* * * ReadPPM * * read a PPM file * * RETURNS: TRUE if successful; FALSE otherwise; mf modified * * SIDE EFFECTS: none * *===========================================================================*/static booleanReadPPM(mf, fpointer) MpegFrame *mf; FILE *fpointer;{ char inputBuffer[71]; char string[71]; char *inputLine; int height = 0, width = 0, maxVal; uint8 junk[4096]; register int y; int state; state = PPM_READ_STATE_MAGIC; while ( state != PPM_READ_STATE_DONE ) { if ( fgets(inputBuffer, 71, fpointer) == NULL ) { return FALSE; } inputLine = inputBuffer; if ( inputLine[0] == '#' ) { continue; } if ( inputLine[strlen(inputLine)-1] != '\n' ) { return FALSE; } switch(state) { case PPM_READ_STATE_MAGIC: if ( (inputLine = ScanNextString(inputLine, string)) == NULL ) { return FALSE; } if ( strcmp(string, "P6") != 0 ) { return FALSE; } state = PPM_READ_STATE_WIDTH; /* no break */ case PPM_READ_STATE_WIDTH: if ( (inputLine = ScanNextString(inputLine, string)) == NULL ) { if ( inputLine == inputBuffer ) { return FALSE; } else { break; } } width = atoi(string); state = PPM_READ_STATE_HEIGHT; /* no break */ case PPM_READ_STATE_HEIGHT: if ( (inputLine = ScanNextString(inputLine, string)) == NULL ) { if ( inputLine == inputBuffer ) { return FALSE; } else { break; } } height = atoi(string); state = PPM_READ_STATE_MAXVAL; /* no break */ case PPM_READ_STATE_MAXVAL: if ( (inputLine = ScanNextString(inputLine, string)) == NULL ) { if ( inputLine == inputBuffer ) { return FALSE; } else { break; } } maxVal = atoi(string); state = PPM_READ_STATE_DONE; break; } /* end of switch */ } Fsize_Note(mf->id, width, height); mf->rgb_maxval = maxVal; Frame_AllocPPM(mf); for ( y = 0; y < Fsize_y; y++ ) { fread(mf->ppm_data[y], sizeof(char), 3*Fsize_x, fpointer); /* read the leftover stuff on the right side */ fread(junk, sizeof(char), 3*(width-Fsize_x), fpointer); } return TRUE;}/*===========================================================================* * * ReadYUV * * read a YUV file * * RETURNS: mf modified * * SIDE EFFECTS: none * *===========================================================================*/static voidReadYUV(mf, fpointer, width, height) MpegFrame *mf; FILE *fpointer; int width; int height;{ register int y; uint8 junk[4096]; Fsize_Note(mf->id, width, height); Frame_AllocYCC(mf); for (y = 0; y < Fsize_y; y++) { /* Y */ fread(mf->orig_y[y], 1, Fsize_x, fpointer); /* read the leftover stuff on the right side */ if ( width != Fsize_x ) { fread(junk, 1, width-Fsize_x, fpointer); } } /* read the leftover stuff on the bottom */ for (y = Fsize_y; y < height; y++) { fread(junk, 1, width, fpointer); } for (y = 0; y < Fsize_y / 2; y++) { /* U */ fread(mf->orig_cb[y], 1, Fsize_x / 2, fpointer); /* read the leftover stuff on the right side */ if ( width != Fsize_x ) { fread(junk, 1, (width-Fsize_x)/2, fpointer); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -