home *** CD-ROM | disk | FTP | other *** search
- /*
- * PostProcessing.cpp
- *
- * Copyright (C) Alberto Vigata - January 2000 - ultraflask@yahoo.com
- *
- * This file is part of FlasKMPEG, a free MPEG to MPEG/AVI converter
- *
- * FlasKMPEG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * FlasKMPEG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
- #include <windows.h>
- #include "flaskmpeg.h"
- #include ".\resizer\vbitmap.h"
- #include ".\resizer\resizer.h"
- #include ".\Video\Deinterlacer\Deinterlacer.h"
- #include ".\postprocessing.h"
-
- struct TPostRun{
- int cropWidthFlag;
- int cropHeightFlag;
- Pixel32 *buffer;
- VBitmap temp;
- VBitmap deinterlacer_output;
- Pixel32 *deinterlacer_output_data;
-
- } PostRun;
-
- #include ".\Video\VideoWrapper.h"
- #include "subpic\subpic.h"
- extern VideoWrapper *myVideo;
-
- //Post processing functions
- int PostProcessingStart(VBitmap *source, VBitmap *dest, TPPost *pp){
-
-
- if( !source || !dest || !pp )
- return 0;
-
- PostRun.cropWidthFlag = 0;
- PostRun.cropHeightFlag = 0;
- PostRun.buffer = NULL;
- dest->offset = 0;
- // init resizer
- PrepareResizer(pp->resWidth, pp->resHeight, pp->doAR, pp->iDAR, pp->filterMode, source);
-
- if(pp->deinterlace)
- {
- TDeinterlacerConfig config;
- config.blend = pp->blend_fields;
- config.threshold= pp->threshold;
-
- // Start deinterlacer
- StartDeinterlacer(source->w, source->h, &config);
- PostRun.deinterlacer_output_data = new Pixel32[source->w*source->h];
- PostRun.deinterlacer_output.init( PostRun.deinterlacer_output_data
- , source->w
- , source->h
- , 32);
- PostRun.deinterlacer_output.AlignTo4();
- }
-
- if( pp->crop )
- if(pp->cropHeight < pp->resHeight )
- PostRun.cropHeightFlag = 1;
-
- // prepare buffer if crop width
- if( pp->crop )
- if(pp->cropWidth < pp->resWidth){
- if( !(PostRun.buffer = (Pixel32 *)malloc(pp->resWidth*pp->resHeight*4)) )
- return 0;
- PostRun.cropWidthFlag=1;
- }
-
- return 1;
- }
-
- int PostProcess(VBitmap *source_bmp, VBitmap *dest, TPPost *pp){
- int w,h,diff,firstline, width, height;
- VBitmap *source;
- Pixel32 *src, *dst;
-
- if( !source_bmp || !dest || !pp )
- return 0;
-
- if(pp->deinterlace){
- DeInterlace(source_bmp, &PostRun.deinterlacer_output);
- source = &PostRun.deinterlacer_output;
- }
- else
- source = source_bmp;
-
- subpic_apply(source, (double)pp->myClock/27000.0);
-
- // Resize
- if(PostRun.cropWidthFlag){
- PostRun.temp.init(PostRun.buffer, pp->resWidth, pp->resHeight, 32);
- ResizerRun( source, &PostRun.temp);
- }
- else if(PostRun.cropHeightFlag){
- // Run resizer over dest->data
- PostRun.temp.init(dest->data, pp->resWidth, pp->resHeight, 32);
- ResizerRun( source, &PostRun.temp);
- }
- else
- ResizerRun( source, dest);
-
- // Crop
- if( pp->crop ){
- if( PostRun.cropHeightFlag ) //Height cropping
- dest->offset = (pp->resHeight - pp->cropTopOffset - pp->cropHeight ) * pp->resWidth;
- if( PostRun.cropWidthFlag ){
- // Width or Width & Height cropping. Resized image is at PostRun.temp
- dest->offset=0;
- h = pp->cropHeight;
-
- firstline = pp->resHeight - pp->cropTopOffset;
- diff = pp->cropLeftOffset + (pp->resWidth -pp->cropWidth - pp->cropLeftOffset);
- dst = (Pixel32 *)dest->data + pp->cropWidth * pp->cropHeight -1;
- src = PostRun.temp.data + pp->cropLeftOffset + (firstline - 1)*pp->resWidth + pp->cropWidth - 1;
-
-
- do{
-
- w = pp->cropWidth;
- do{
- *dst-- = *src--;
- }while(--w);
- src = src - diff;
- }while(--h);
-
-
- }
- }
- else
- dest->offset = 0; // No cropping
-
-
- // Letterbox
- width = pp->crop ? pp->cropWidth : pp->resWidth;
- height = pp->crop ? pp->cropHeight : pp->resHeight;
-
- if(pp->letterbox){
- //Bottom bar
- if (pp->letterboxBottom>0){
- h = pp->letterboxBottom;
- dst = dest->Address();
- do {
- w = width;
- do {
- *dst++ = 0;
- } while(--w);
- } while(--h);
- }
-
- //Top bar
-
- if (pp->letterboxTop>0){
- h = pp->letterboxTop;
- // Point to last pixel
- dst = dest->Address() + width * height - 1;
- do {
- w = width;
- do {
- *dst-- = 0;
- } while(--w);
- } while(--h);
- }
-
- // Left Bar
- if (pp->letterboxLeft >0 ){
- h = height;
- do {
- // Point to first pixel of last row
- w = pp->letterboxLeft;
- dst = dest->Address() + (h-1) * width;
- do {
- *dst++ = 0;
- } while(--w);
- } while(--h);
- }
-
- // Right Bar
- if (pp->letterboxRight >0 ){
- h = height;
- do {
- w = pp->letterboxRight;
- // Point to last pixel
- dst = dest->Address() + h * width - 1;
- do {
- *dst-- = 0;
- } while(--w);
- } while(--h);
- }
- }
- // That was it
-
- return 1;
- }
-
- int PostProcessingStop(TPPost *pp){
-
- UnPrepareResizer();
- // Free horizontal crop buffer if necessary
- if(PostRun.cropWidthFlag)
- if(PostRun.buffer){
- free(PostRun.buffer);
- PostRun.buffer =NULL;
- }
- if(pp->deinterlace)
- {
- StopDeinterlacer();
- delete [] PostRun.deinterlacer_output_data;
- }
-
-
- return 0;
- }
-
-
- // Auxiliary Post processing functions
-
- // Fix absurd post processing settings
- void FixPPostSettings(TPPost *pp){
-
- if(pp->cropWidth>pp->resWidth)
- pp->cropWidth = pp->resWidth;
- if(pp->cropHeight > pp->resHeight)
- pp->cropHeight = pp->resHeight;
-
- }
-
- int CheckVideoParameters(TPPost *pp){
- int w,h;
-
- FixPPostSettings(pp);
- // Image dimension settings
- if( (pp->cropHeight%16 != 0) || (pp->cropWidth%16 != 0) )
- return 0;
- if( (pp->resWidth%16 != 0) || (pp->resHeight%16 != 0) )
- return 0;
-
- //Crop Checkings
- // Crop widht&height must be less than input image resolution
- if( pp->crop && (pp->cropHeight > pp->resHeight) )
- return 0;
- if( pp->crop && (pp->cropWidth > pp->resWidth) )
- return 0;
- if( pp->crop && ((pp->cropTopOffset + pp->cropHeight) > pp->resHeight) )
- return 0;
- if( pp->crop && ((pp->cropLeftOffset + pp->cropWidth) > pp->resWidth) )
- return 0;
-
- if( (pp->cropHeight < 0) || (pp->cropWidth < 0) )
- return 0;
- if( pp->crop && ((pp->cropTopOffset<0) || (pp->cropTopOffset > pp->cropHeight-16)) )
- return 0;
- if( pp->crop && ((pp->cropLeftOffset<0) || (pp->cropLeftOffset > pp->cropWidth-16)) )
- return 0;
-
- // image size
- if( pp->resWidth > 1024 || pp->resHeight > 1024)
- return 0;
-
- // Letterboxing
- w = pp->crop ? pp->cropWidth : pp->resWidth;
- h = pp->crop ? pp->cropHeight : pp->resHeight;
-
- if( pp->letterbox && (pp->letterboxLeft>w || pp->letterboxRight >w
- || pp->letterboxTop >h || pp->letterboxBottom>h))
- return 0;
- if( pp->letterbox && (pp->letterboxLeft<0 || pp->letterboxRight <0
- || pp->letterboxTop <0 || pp->letterboxBottom<0))
- return 0;
-
-
- return 1;
- }
-
- void SetPPostConfig( TConfig *c, TPPost *pp){
-
- c->options.crop = pp->crop;
- c->options.cropWidth = pp->cropWidth;
- c->options.cropHeight = pp->cropHeight;
- c->options.cropTopOffset = pp->cropTopOffset;
- c->options.cropLeftOffset = pp->cropLeftOffset;
-
- c->options.letterbox = pp->letterbox;
- c->options.letterboxBottom= pp->letterboxBottom;
- c->options.letterboxTop = pp->letterboxTop;
- c->options.letterboxLeft = pp->letterboxLeft;
- c->options.letterboxRight = pp->letterboxRight;
-
- c->options.InterpolatedWidth = pp->resWidth;
- c->options.InterpolatedHeight = pp->resHeight;
- c->options.filter = pp->filterMode;
- c->options.keepAspect = pp->doAR;
-
- c->options.deinterlace = pp->deinterlace;
- c->options.blend = pp->blend_fields;
- c->options.threshold = pp->threshold;
- }
-
- void GetPPostConfig( TConfig *c, TPPost *pp){
-
- pp->crop = c->options.crop;
- pp->cropWidth = c->options.cropWidth;
- pp->cropHeight = c->options.cropHeight;
- pp->cropTopOffset = c->options.cropTopOffset;
- pp->cropLeftOffset= c->options.cropLeftOffset;
-
-
- pp->letterbox = c->options.letterbox;
- pp->letterboxBottom = c->options.letterboxBottom;
- pp->letterboxTop = c->options.letterboxTop;
- pp->letterboxLeft = c->options.letterboxLeft;
- pp->letterboxRight = c->options.letterboxRight;
-
- pp->resWidth = c->options.InterpolatedWidth ;
- pp->resHeight = c->options.InterpolatedHeight;
- pp->filterMode = c->options.filter;
- pp->doAR = c->options.keepAspect;
-
- pp->deinterlace = c->options.deinterlace;
- pp->blend_fields = c->options.blend;
- pp->threshold = c->options.threshold;
-
- }
-
-