home *** CD-ROM | disk | FTP | other *** search
- /*
- * Crop.cpp
- *
- *
- * Copyright (C) Alberto Vigata - January 2000
- *
- * 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 "Crop.h"
- #include "Auxiliary.h"
- #include "Debug.h"
-
-
- int CropRGB32(CFrame *source, CFrame *dest, TCropConfig *config) {
-
- if(!source || !dest)
- return 0;
-
-
- ui8* src = source->GetBuffer();
- ui8* dst = dest->GetBuffer();
- ui8 *src_start;
- ui32 src_w = source->GetWidth(), src_h = source->GetHeight();
- ui32 dst_w = dest->GetWidth(), dst_h = dest->GetHeight();
- ui32 nSrcPitch = source->GetPitch();
- ui32 nDstPitch = dest->GetPitch();
-
- ui32 crop_w = config->right - config->left;
- ui32 crop_h = config->bottom - config->top;
-
-
- // If the crop width is the same as the output
- // height there, just copy the raw data.
- if( crop_w == src_w )
- {
- src_start = src + config->top * nSrcPitch;
- flmemcpy( dst, src_start, crop_h * nSrcPitch );
- }
- else // copy stride by stride
- {
- // We are dealing with bottom-up dibs
- // so last row in memory is the first scanline
- src_start = src + ( src_h - 1 - config->top ) * nSrcPitch
- + config->left * sizeof(Pixel32) ;
-
- // Advance the destination to the last row
- dst += (dst_h - 1) * nDstPitch;
-
- int h = crop_h; // number of strides to copy
- do
- {
- flmemcpy( dst, src_start, crop_w * sizeof(Pixel32) );
- src_start-= nSrcPitch;
- dst -= nDstPitch;
- }while(--h);
- }
-
-
- return 0;
- }
-
-
- void CropPlanar( Pixel8 *src, Pixel8 *dst, int src_w, int src_h, int dst_w, int dst_h,
- TCropConfig *config)
- {
- if(!src || !dst)
- return;
-
- ui32 crop_w = config->right - config->left;
- ui32 crop_h = config->bottom - config->top;
-
- Pixel8 *src_start = src + config->top/2*2 * src_w + config->left/2*2;
-
- // If the crop width is the same as the output
- // height there, just copy the raw data.
- if( crop_w == src_w )
- {
- flmemcpy( dst, src_start, crop_h * src_w );
- }
- else // copy stride by stride
- {
- int h = crop_h; // number of strides to copy
- do
- {
- flmemcpy( dst, src_start, crop_w );
- src_start+= src_w;
- dst += dst_w;
- }while(--h);
- }
- }
-
- int CropYV12(CFrame *source, CFrame *dest, TCropConfig *config)
- {
- TCropConfig sUVConfig;
-
- int sw = source->GetWidth();
- int sh = source->GetHeight();
-
- int shw = sw>>1;
- int shh = sh>>1;
-
- int dw = config->right - config->left;
- int dh = config->bottom - config->top;
-
- int dhw = dw >> 1;
- int dhh = dh >> 1;
-
- int sysize = sw*sh;
- int scrsize = shw * shh;
-
- int dysize = dw*dh;
- int dcrsize = dhw * dhh;
-
- sUVConfig.bottom = config->bottom >> 1;
- sUVConfig.top = config->top >> 1;
- sUVConfig.left = config->left >> 1;
- sUVConfig.right = config->right >> 1;
-
- Pixel8 *pSrc = (Pixel8 *)source->GetBuffer();
- Pixel8 *pDst = (Pixel8 *)dest->GetBuffer();
-
- CropPlanar( pSrc, pDst, sw, sh, dw, dh, config);
- // V
- CropPlanar( pSrc + sysize,
- pDst + dysize, shw, shh, dhw, dhh, &sUVConfig);
- // U
- CropPlanar( pSrc + sysize + scrsize,
- pDst + dysize + dcrsize,
- shw, shh, dhw , dhh, &sUVConfig);
-
-
- return 0;
- }
-
- int Crop(CFrame *source, CFrame *dest, TCropConfig *config)
- {
- if(!source || !dest)
- return 0;
-
- int crop_w = config->right - config->left;
- int crop_h = config->bottom - config->top;
-
- if( crop_w != dest->GetWidth() ||
- crop_h != dest->GetHeight() )
- {
- DBG_STR((str, "Crop - Invalid Parameters\n"))
- return 0;
- }
-
- switch( source->GetFormat() )
- {
- case FRAME_RGB32:
- return CropRGB32(source, dest, config);
- break;
- case FRAME_YV12:
- return CropYV12( source, dest, config);
- break;
- default:
- dest->SetFrame( source );
- break;
- }
- return 1;
- }
-
-
- FlCrop::FlCrop()
- {
- memset( &m_cfg, 0, sizeof m_cfg );
- m_bConfigured = false;
- }
-
-
- int FlCrop::StartSimple()
- {
- return m_bConfigured == true ? 1 : 0;
- }
-
- int FlCrop::Configure( void *conf, int confsize)
- {
- int res;
-
- FLASSERT( confsize==sizeof(TCropConfig) )
- TCropConfig cfg = *(TCropConfig *)conf;
-
-
- // Validate configuration
- if( (cfg.right-cfg.left)%16==0 &&
- (cfg.bottom-cfg.top)%16==0 &&
- (cfg.right-cfg.left)>0 &&
- (cfg.bottom-cfg.top)>0 )
- {
- m_cfg = cfg;
- m_bConfigured = true;
- res = flfil_ok;
- }
- else {
- m_bConfigured = false;
- res = flfil_error;
- }
-
- return res;
- }
-
- int FlCrop::GetFilterConf( flfilter_conf *fc )
- {
- if(!m_bConfigured)
- {
- DBG_STR((str, "FlCrop::GetConf - You need to configure first\n"))
- return 0;
- }
-
- if(!fc)
- return 0;
-
- *fc = m_fc;
-
- return 1;
- }
-
- int FlCrop::ValFilterConf( flfilter_conf *fc )
- {
- if(!m_bConfigured)
- {
- DBG_STR((str, "FlCrop::Query - You need to configure first\n"))
- return flfil_error;
- }
-
- if( m_cfg.left < 0 || m_cfg.right>fc->iw ||
- m_cfg.top < 0 || m_cfg.bottom>fc->ih ) {
- return flfil_error;
- }
-
- fc->od = fc->id;
- fc->ow = m_cfg.right - m_cfg.left;
- fc->oh = m_cfg.bottom - m_cfg.top;
- fc->oprovided = 0;
- fc->op = 0;
- fc->ocanmodify = 1;
-
- m_fc = *fc;
-
- return 1;
- }
-
- int FlCrop::ProcessSimple( CFrame *in, CFrame *out )
- {
- return Crop( in, out, &m_cfg );
- }
-
- int FlCrop::StopSimple()
- {
- return 1;
- }