mirror of
https://github.com/id-Software/DOOM-3.git
synced 2026-03-19 16:39:27 +01:00
hello world
This commit is contained in:
105
neo/tools/compilers/roqvq/NSBitmapImageRep.cpp
Normal file
105
neo/tools/compilers/roqvq/NSBitmapImageRep.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 GPL Source Code
|
||||
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
|
||||
|
||||
Doom 3 Source Code 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#include "../../../idlib/precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "roq.h"
|
||||
|
||||
void R_LoadImage( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp, bool makePowerOf2 );
|
||||
|
||||
NSBitmapImageRep::NSBitmapImageRep( void ) {
|
||||
bmap = NULL;
|
||||
width = 0;
|
||||
height = 0;
|
||||
timestamp = 0;
|
||||
}
|
||||
|
||||
NSBitmapImageRep::NSBitmapImageRep( const char *filename ) {
|
||||
|
||||
R_LoadImage( filename, &bmap, &width, &height, ×tamp, false );
|
||||
if (!width || !height) {
|
||||
common->FatalError( "roqvq: unable to load image %s\n", filename );
|
||||
}
|
||||
}
|
||||
|
||||
NSBitmapImageRep::NSBitmapImageRep( int wide, int high ) {
|
||||
bmap = (byte *)Mem_ClearedAlloc( wide * high * 4 );
|
||||
width = wide;
|
||||
height = high;
|
||||
}
|
||||
|
||||
void R_StaticFree( void *data );
|
||||
|
||||
NSBitmapImageRep::~NSBitmapImageRep() {
|
||||
R_StaticFree( bmap );
|
||||
bmap = NULL;
|
||||
}
|
||||
|
||||
int NSBitmapImageRep::samplesPerPixel( void ) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
int NSBitmapImageRep::pixelsWide( void ) {
|
||||
return width;
|
||||
}
|
||||
|
||||
int NSBitmapImageRep::pixelsHigh( void ) {
|
||||
return height;
|
||||
}
|
||||
|
||||
byte * NSBitmapImageRep::bitmapData( void ) {
|
||||
return bmap;
|
||||
}
|
||||
|
||||
bool NSBitmapImageRep::hasAlpha( void ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NSBitmapImageRep::isPlanar( void ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NSBitmapImageRep &NSBitmapImageRep::operator=( const NSBitmapImageRep &a ) {
|
||||
|
||||
// check for assignment to self
|
||||
if ( this == &a ) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (bmap) {
|
||||
Mem_Free(bmap);
|
||||
}
|
||||
bmap = (byte *)Mem_Alloc( a.width * a.height * 4 );
|
||||
memcpy( bmap, a.bmap, a.width * a.height * 4 );
|
||||
width = a.width;
|
||||
height = a.height;
|
||||
timestamp = a.timestamp;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
1696
neo/tools/compilers/roqvq/codec.cpp
Normal file
1696
neo/tools/compilers/roqvq/codec.cpp
Normal file
File diff suppressed because it is too large
Load Diff
108
neo/tools/compilers/roqvq/codec.h
Normal file
108
neo/tools/compilers/roqvq/codec.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 GPL Source Code
|
||||
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
|
||||
|
||||
Doom 3 Source Code 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#ifndef __codec_h__
|
||||
#define __codec_h__
|
||||
|
||||
#define MAXERRORMAX 200
|
||||
#define IPSIZE int
|
||||
const float MOTION_MIN = 1.0f;
|
||||
const float MIN_SNR = 3.0f;
|
||||
|
||||
#define FULLFRAME 0
|
||||
#define JUSTMOTION 1
|
||||
|
||||
#define VQDATA double
|
||||
|
||||
#include "gdefs.h"
|
||||
#include "roq.h"
|
||||
#include "quaddefs.h"
|
||||
|
||||
class codec {
|
||||
public:
|
||||
codec();
|
||||
~codec();
|
||||
|
||||
void SparseEncode( void );
|
||||
void EncodeNothing( void );
|
||||
void IRGBtab(void);
|
||||
void InitImages(void);
|
||||
void QuadX( int startX, int startY, int quadSize);
|
||||
void InitQStatus();
|
||||
float Snr(byte *old, byte *bnew, int size);
|
||||
void FvqData( byte *bitmap, int size, int realx, int realy, quadcel *pquad, bool clamp);
|
||||
void GetData( unsigned char *iData, int qSize, int startX, int startY, NSBitmapImageRep *bitmap);
|
||||
int ComputeMotionBlock( byte *old, byte *bnew, int size);
|
||||
void VqData8( byte *cel, quadcel *pquad);
|
||||
void VqData4( byte *cel, quadcel *pquad);
|
||||
void VqData2( byte *cel, quadcel *pquad);
|
||||
int MotMeanY(void);
|
||||
int MotMeanX(void);
|
||||
void SetPreviousImage( const char*filename, NSBitmapImageRep *timage );
|
||||
int BestCodeword( unsigned char *tempvector, int dimension, VQDATA **codebook );
|
||||
private:
|
||||
|
||||
void VQ( const int numEntries, const int dimension, const unsigned char *vectors, float *snr, VQDATA **codebook, const bool optimize );
|
||||
void Sort( float *list, int *intIndex, int numElements );
|
||||
void Segment( int *alist, float *flist, int numElements, float rmse);
|
||||
void LowestQuad( quadcel*qtemp, int* status, float* snr, int bweigh);
|
||||
void MakePreviousImage( quadcel *pquad );
|
||||
float GetCurrentRMSE( quadcel *pquad );
|
||||
int GetCurrentQuadOutputSize( quadcel *pquad );
|
||||
int AddQuad( quadcel *pquad, int lownum );
|
||||
|
||||
NSBitmapImageRep *image;
|
||||
NSBitmapImageRep *newImage;
|
||||
NSBitmapImageRep *previousImage[2]; // the ones in video ram and offscreen ram
|
||||
int numQuadCels;
|
||||
int whichFrame;
|
||||
int slop;
|
||||
bool detail;
|
||||
int onQuad;
|
||||
int initRGBtab;
|
||||
quadcel *qStatus;
|
||||
int dxMean;
|
||||
int dyMean;
|
||||
int codebooksize;
|
||||
int index2[256];
|
||||
int overAmount;
|
||||
int pixelsWide;
|
||||
int pixelsHigh;
|
||||
int codebookmade;
|
||||
bool used2[256];
|
||||
bool used4[256];
|
||||
int dimension2;
|
||||
int dimension4;
|
||||
|
||||
byte luty[256];
|
||||
byte *luti;
|
||||
VQDATA **codebook2;
|
||||
VQDATA **codebook4;
|
||||
|
||||
};
|
||||
|
||||
#endif // __codec_h__
|
||||
68
neo/tools/compilers/roqvq/gdefs.h
Normal file
68
neo/tools/compilers/roqvq/gdefs.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 GPL Source Code
|
||||
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
|
||||
|
||||
Doom 3 Source Code 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#ifndef __gdefs_h__
|
||||
#define __gdefs_h__
|
||||
|
||||
/*==================*
|
||||
* TYPE DEFINITIONS *
|
||||
*==================*/
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
#pragma once
|
||||
|
||||
#define dabs(a) (((a)<0) ? -(a) : (a))
|
||||
#define CLAMP(v,l,h) ((v)<(l) ? (l) : (v)>(h) ? (h) : v)
|
||||
#define xswap(a,b) { a^=b; b^=a; a^=b; }
|
||||
#define lum(a) ( 0.2990*(a>>16) + 0.5870*((a>>8)&0xff) + 0.1140*(a&0xff) )
|
||||
#define gsign(a) ((a) < 0 ? -1 : 1)
|
||||
#define mnint(a) ((a) < 0 ? (int)(a - 0.5) : (int)(a + 0.5))
|
||||
#define mmax(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define mmin(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define RGBDIST( src0, src1 ) ( ((src0[0]-src1[0])*(src0[0]-src1[0])) + \
|
||||
((src0[1]-src1[1])*(src0[1]-src1[1])) + \
|
||||
((src0[2]-src1[2])*(src0[2]-src1[2])) )
|
||||
|
||||
#define RGBADIST( src0, src1 ) ( ((src0[0]-src1[0])*(src0[0]-src1[0])) + \
|
||||
((src0[1]-src1[1])*(src0[1]-src1[1])) + \
|
||||
((src0[2]-src1[2])*(src0[2]-src1[2])) + \
|
||||
((src0[3]-src1[3])*(src0[3]-src1[3])) )
|
||||
|
||||
|
||||
#define RMULT 0.2990f // use these for televisions
|
||||
#define GMULT 0.5870f
|
||||
#define BMULT 0.1140f
|
||||
|
||||
#define RIEMULT -0.16874f
|
||||
#define RQEMULT 0.50000f
|
||||
#define GIEMULT -0.33126f
|
||||
#define GQEMULT -0.41869f
|
||||
#define BIEMULT 0.50000f
|
||||
#define BQEMULT -0.08131f
|
||||
|
||||
#endif // gdefs
|
||||
131
neo/tools/compilers/roqvq/quaddefs.h
Normal file
131
neo/tools/compilers/roqvq/quaddefs.h
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 GPL Source Code
|
||||
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
|
||||
|
||||
Doom 3 Source Code 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#ifndef __quaddefs_h__
|
||||
#define __quaddefs_h__
|
||||
|
||||
#pragma once
|
||||
|
||||
#define DEP 0
|
||||
#define FCC 1
|
||||
#define CCC 2
|
||||
#define SLD 3
|
||||
#define PAT 4
|
||||
#define MOT 5
|
||||
#define DEAD 6
|
||||
|
||||
#define COLA 0
|
||||
#define COLB 1
|
||||
#define COLC 2
|
||||
#define COLS 3
|
||||
#define COLPATA 4
|
||||
#define COLPATB 5
|
||||
#define COLPATS 6
|
||||
#define GENERATION 7
|
||||
|
||||
#define CCCBITMAP 0
|
||||
#define FCCDOMAIN 1
|
||||
#define PATNUMBER 2
|
||||
#define PATNUMBE2 3
|
||||
#define PATNUMBE3 4
|
||||
#define PATNUMBE4 5
|
||||
#define PATNUMBE5 6
|
||||
|
||||
#define MAXSIZE 16
|
||||
#define MINSIZE 4
|
||||
|
||||
#define RoQ_ID 0x1084
|
||||
#define RoQ_QUAD 0x1000
|
||||
#define RoQ_PUZZLE_QUAD 0x1003
|
||||
#define RoQ_QUAD_HANG 0x1013
|
||||
#define RoQ_QUAD_SMALL 0x1010
|
||||
#define RoQ_QUAD_INFO 0x1001
|
||||
#define RoQ_QUAD_VQ 0x1011
|
||||
#define RoQ_QUAD_JPEG 0x1012
|
||||
#define RoQ_QUAD_CODEBOOK 0x1002
|
||||
|
||||
typedef struct {
|
||||
byte size; // 32, 16, 8, or 4
|
||||
word xat; // where is it at on the screen
|
||||
word yat; //
|
||||
} shortQuadCel;
|
||||
|
||||
typedef struct {
|
||||
byte size; // 32, 16, 8, or 4
|
||||
word xat; // where is it at on the screen
|
||||
word yat; //
|
||||
|
||||
float cccsnr; // ccc bitmap snr to actual image
|
||||
float fccsnr; // fcc bitmap snr to actual image
|
||||
float motsnr; // delta snr to previous image
|
||||
float sldsnr; // solid color snr
|
||||
float patsnr;
|
||||
float dctsnr;
|
||||
float rsnr; // what's the current snr
|
||||
|
||||
unsigned int cola; // color a for ccc
|
||||
unsigned int colb; // color b for ccc
|
||||
unsigned int colc; // color b for ccc
|
||||
unsigned int sldcol; // sold color
|
||||
unsigned int colpata;
|
||||
unsigned int colpatb;
|
||||
unsigned int colpats;
|
||||
unsigned int bitmap; // ccc bitmap
|
||||
|
||||
word domain; // where to copy from for fcc
|
||||
word patten[5]; // which pattern
|
||||
|
||||
int status;
|
||||
bool mark;
|
||||
float snr[DEAD+1]; // snrssss
|
||||
} quadcel;
|
||||
|
||||
typedef struct {
|
||||
float snr[DEAD+1]; // snrssss
|
||||
unsigned int cols[8];
|
||||
unsigned int bitmaps[7]; // ccc bitmap
|
||||
} dataQuadCel;
|
||||
|
||||
typedef struct {
|
||||
float normal;
|
||||
unsigned short int index;
|
||||
} norm;
|
||||
|
||||
typedef struct {
|
||||
unsigned char dtlMap[256];
|
||||
int r[4];
|
||||
int g[4];
|
||||
int b[4];
|
||||
int a[4];
|
||||
float ymean;
|
||||
} dtlCel;
|
||||
|
||||
typedef struct {
|
||||
byte r,g,b,a;
|
||||
} pPixel;
|
||||
|
||||
#endif // quaddef
|
||||
855
neo/tools/compilers/roqvq/roq.cpp
Normal file
855
neo/tools/compilers/roqvq/roq.cpp
Normal file
@@ -0,0 +1,855 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 GPL Source Code
|
||||
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
|
||||
|
||||
Doom 3 Source Code 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#include "../../../idlib/precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "roq.h"
|
||||
#include "codec.h"
|
||||
|
||||
roq *theRoQ; // current roq file
|
||||
|
||||
roq::roq( void )
|
||||
{
|
||||
image = 0;
|
||||
quietMode = false;
|
||||
encoder = 0;
|
||||
previousSize = 0;
|
||||
lastFrame = false;
|
||||
dataStuff=false;
|
||||
}
|
||||
|
||||
roq::~roq( void )
|
||||
{
|
||||
if (image) delete image;
|
||||
if (encoder) delete encoder;
|
||||
return;
|
||||
}
|
||||
|
||||
void roq::EncodeQuietly( bool which )
|
||||
{
|
||||
quietMode = which;
|
||||
}
|
||||
|
||||
bool roq::IsQuiet( void )
|
||||
{
|
||||
return quietMode;
|
||||
}
|
||||
|
||||
bool roq::IsLastFrame( void )
|
||||
{
|
||||
return lastFrame;
|
||||
}
|
||||
|
||||
bool roq::Scaleable( void )
|
||||
{
|
||||
return paramFile->IsScaleable();
|
||||
}
|
||||
|
||||
bool roq::ParamNoAlpha( void )
|
||||
{
|
||||
return paramFile->NoAlpha();
|
||||
}
|
||||
|
||||
bool roq::MakingVideo( void )
|
||||
{
|
||||
return true; //paramFile->timecode];
|
||||
}
|
||||
|
||||
bool roq::SearchType( void )
|
||||
{
|
||||
return paramFile->SearchType();
|
||||
}
|
||||
|
||||
bool roq::HasSound( void )
|
||||
{
|
||||
return paramFile->HasSound();
|
||||
}
|
||||
|
||||
int roq::PreviousFrameSize( void )
|
||||
{
|
||||
return previousSize;
|
||||
}
|
||||
|
||||
int roq::FirstFrameSize( void )
|
||||
{
|
||||
return paramFile->FirstFrameSize();
|
||||
}
|
||||
|
||||
int roq::NormalFrameSize( void )
|
||||
{
|
||||
return paramFile->NormalFrameSize();
|
||||
}
|
||||
|
||||
const char * roq::CurrentFilename( void )
|
||||
{
|
||||
return currentFile.c_str();
|
||||
}
|
||||
|
||||
void roq::EncodeStream( const char *paramInputFile )
|
||||
{
|
||||
int onFrame;
|
||||
idStr f0, f1, f2;
|
||||
int morestuff;
|
||||
|
||||
onFrame = 1;
|
||||
|
||||
encoder = new codec;
|
||||
paramFile = new roqParam;
|
||||
paramFile->numInputFiles = 0;
|
||||
|
||||
paramFile->InitFromFile( paramInputFile );
|
||||
|
||||
if (!paramFile->NumberOfFrames()) {
|
||||
return;
|
||||
}
|
||||
|
||||
InitRoQFile( paramFile->outputFilename);
|
||||
|
||||
numberOfFrames = paramFile->NumberOfFrames();
|
||||
|
||||
if (paramFile->NoAlpha()==true) common->Printf("encodeStream: eluding alpha\n");
|
||||
|
||||
f0 = "";
|
||||
f1 = paramFile->GetNextImageFilename();
|
||||
if (( paramFile->MoreFrames() == true )) {
|
||||
f2 = paramFile->GetNextImageFilename();
|
||||
}
|
||||
morestuff = numberOfFrames;
|
||||
|
||||
while( morestuff ) {
|
||||
LoadAndDisplayImage( f1 );
|
||||
|
||||
if (onFrame==1) {
|
||||
encoder->SparseEncode();
|
||||
// WriteLossless();
|
||||
} else {
|
||||
if (!strcmp( f0, f1 ) && strcmp( f1, f2) ) {
|
||||
WriteHangFrame();
|
||||
} else {
|
||||
encoder->SparseEncode();
|
||||
}
|
||||
}
|
||||
|
||||
onFrame++;
|
||||
f0 = f1;
|
||||
f1 = f2;
|
||||
if (paramFile->MoreFrames() == true) {
|
||||
f2 = paramFile->GetNextImageFilename();
|
||||
}
|
||||
morestuff--;
|
||||
session->UpdateScreen();
|
||||
}
|
||||
|
||||
// if (numberOfFrames != 1) {
|
||||
// if (image->hasAlpha() && paramFile->NoAlpha()==false) {
|
||||
// lastFrame = true;
|
||||
// encoder->SparseEncode();
|
||||
// } else {
|
||||
// WriteLossless();
|
||||
// }
|
||||
// }
|
||||
CloseRoQFile();
|
||||
}
|
||||
|
||||
void roq::Write16Word( word *aWord, idFile *stream )
|
||||
{
|
||||
byte a, b;
|
||||
|
||||
a = *aWord & 0xff;
|
||||
b = *aWord >> 8;
|
||||
|
||||
stream->Write( &a, 1 );
|
||||
stream->Write( &b, 1 );
|
||||
}
|
||||
|
||||
void roq::Write32Word( unsigned int *aWord, idFile *stream )
|
||||
{
|
||||
byte a, b, c, d;
|
||||
|
||||
a = *aWord & 0xff;
|
||||
b = (*aWord >> 8) & 0xff;
|
||||
c = (*aWord >> 16) & 0xff;
|
||||
d = (*aWord >> 24) & 0xff;
|
||||
|
||||
stream->Write( &a, 1 );
|
||||
stream->Write( &b, 1 );
|
||||
stream->Write( &c, 1 );
|
||||
stream->Write( &d, 1 );
|
||||
}
|
||||
|
||||
int roq::SizeFile( idFile *ftosize )
|
||||
{
|
||||
return ftosize->Length();
|
||||
}
|
||||
|
||||
/* Expanded data destination object for stdio output */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_destination_mgr pub; /* public fields */
|
||||
|
||||
byte* outfile; /* target stream */
|
||||
int size;
|
||||
} my_destination_mgr;
|
||||
|
||||
typedef my_destination_mgr * my_dest_ptr;
|
||||
|
||||
|
||||
/*
|
||||
* Initialize destination --- called by jpeg_start_compress
|
||||
* before any data is actually written.
|
||||
*/
|
||||
|
||||
void roq::JPEGInitDestination (j_compress_ptr cinfo) {
|
||||
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
|
||||
|
||||
dest->pub.next_output_byte = dest->outfile;
|
||||
dest->pub.free_in_buffer = dest->size;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Empty the output buffer --- called whenever buffer fills up.
|
||||
*
|
||||
* In typical applications, this should write the entire output buffer
|
||||
* (ignoring the current state of next_output_byte & free_in_buffer),
|
||||
* reset the pointer & count to the start of the buffer, and return true
|
||||
* indicating that the buffer has been dumped.
|
||||
*
|
||||
* In applications that need to be able to suspend compression due to output
|
||||
* overrun, a FALSE return indicates that the buffer cannot be emptied now.
|
||||
* In this situation, the compressor will return to its caller (possibly with
|
||||
* an indication that it has not accepted all the supplied scanlines). The
|
||||
* application should resume compression after it has made more room in the
|
||||
* output buffer. Note that there are substantial restrictions on the use of
|
||||
* suspension --- see the documentation.
|
||||
*
|
||||
* When suspending, the compressor will back up to a convenient restart point
|
||||
* (typically the start of the current MCU). next_output_byte & free_in_buffer
|
||||
* indicate where the restart point will be if the current call returns FALSE.
|
||||
* Data beyond this point will be regenerated after resumption, so do not
|
||||
* write it out when emptying the buffer externally.
|
||||
*/
|
||||
|
||||
boolean roq::JPEGEmptyOutputBuffer (j_compress_ptr cinfo) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Compression initialization.
|
||||
* Before calling this, all parameters and a data destination must be set up.
|
||||
*
|
||||
* We require a write_all_tables parameter as a failsafe check when writing
|
||||
* multiple datastreams from the same compression object. Since prior runs
|
||||
* will have left all the tables marked sent_table=true, a subsequent run
|
||||
* would emit an abbreviated stream (no tables) by default. This may be what
|
||||
* is wanted, but for safety's sake it should not be the default behavior:
|
||||
* programmers should have to make a deliberate choice to emit abbreviated
|
||||
* images. Therefore the documentation and examples should encourage people
|
||||
* to pass write_all_tables=true; then it will take active thought to do the
|
||||
* wrong thing.
|
||||
*/
|
||||
|
||||
void roq::JPEGStartCompress (j_compress_ptr cinfo, bool write_all_tables) {
|
||||
if (cinfo->global_state != CSTATE_START)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
|
||||
if (write_all_tables)
|
||||
jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */
|
||||
|
||||
/* (Re)initialize error mgr and destination modules */
|
||||
(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
|
||||
(*cinfo->dest->init_destination) (cinfo);
|
||||
/* Perform master selection of active modules */
|
||||
jinit_compress_master(cinfo);
|
||||
/* Set up for the first pass */
|
||||
(*cinfo->master->prepare_for_pass) (cinfo);
|
||||
/* Ready for application to drive first pass through jpeg_write_scanlines
|
||||
* or jpeg_write_raw_data.
|
||||
*/
|
||||
cinfo->next_scanline = 0;
|
||||
cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write some scanlines of data to the JPEG compressor.
|
||||
*
|
||||
* The return value will be the number of lines actually written.
|
||||
* This should be less than the supplied num_lines only in case that
|
||||
* the data destination module has requested suspension of the compressor,
|
||||
* or if more than image_height scanlines are passed in.
|
||||
*
|
||||
* Note: we warn about excess calls to jpeg_write_scanlines() since
|
||||
* this likely signals an application programmer error. However,
|
||||
* excess scanlines passed in the last valid call are *silently* ignored,
|
||||
* so that the application need not adjust num_lines for end-of-image
|
||||
* when using a multiple-scanline buffer.
|
||||
*/
|
||||
|
||||
JDIMENSION roq::JPEGWriteScanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines, JDIMENSION num_lines) {
|
||||
JDIMENSION row_ctr, rows_left;
|
||||
|
||||
if (cinfo->global_state != CSTATE_SCANNING)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
if (cinfo->next_scanline >= cinfo->image_height)
|
||||
WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
|
||||
|
||||
/* Call progress monitor hook if present */
|
||||
if (cinfo->progress != NULL) {
|
||||
cinfo->progress->pass_counter = (long) cinfo->next_scanline;
|
||||
cinfo->progress->pass_limit = (long) cinfo->image_height;
|
||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
||||
}
|
||||
|
||||
/* Give master control module another chance if this is first call to
|
||||
* jpeg_write_scanlines. This lets output of the frame/scan headers be
|
||||
* delayed so that application can write COM, etc, markers between
|
||||
* jpeg_start_compress and jpeg_write_scanlines.
|
||||
*/
|
||||
if (cinfo->master->call_pass_startup)
|
||||
(*cinfo->master->pass_startup) (cinfo);
|
||||
|
||||
/* Ignore any extra scanlines at bottom of image. */
|
||||
rows_left = cinfo->image_height - cinfo->next_scanline;
|
||||
if (num_lines > rows_left)
|
||||
num_lines = rows_left;
|
||||
|
||||
row_ctr = 0;
|
||||
(*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines);
|
||||
cinfo->next_scanline += row_ctr;
|
||||
return row_ctr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Terminate destination --- called by jpeg_finish_compress
|
||||
* after all data has been written. Usually needs to flush buffer.
|
||||
*
|
||||
* NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
|
||||
* application must deal with any cleanup that should happen even
|
||||
* for error exit.
|
||||
*/
|
||||
|
||||
static int hackSize;
|
||||
|
||||
void roq::JPEGTermDestination (j_compress_ptr cinfo) {
|
||||
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
|
||||
size_t datacount = dest->size - dest->pub.free_in_buffer;
|
||||
hackSize = datacount;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Prepare for output to a stdio stream.
|
||||
* The caller must have already opened the stream, and is responsible
|
||||
* for closing it after finishing compression.
|
||||
*/
|
||||
|
||||
void roq::JPEGDest (j_compress_ptr cinfo, byte* outfile, int size) {
|
||||
my_dest_ptr dest;
|
||||
|
||||
/* The destination object is made permanent so that multiple JPEG images
|
||||
* can be written to the same file without re-executing jpeg_stdio_dest.
|
||||
* This makes it dangerous to use this manager and a different destination
|
||||
* manager serially with the same JPEG object, because their private object
|
||||
* sizes may be different. Caveat programmer.
|
||||
*/
|
||||
if (cinfo->dest == NULL) { /* first time for this JPEG object? */
|
||||
cinfo->dest = (struct jpeg_destination_mgr *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
sizeof(my_destination_mgr));
|
||||
}
|
||||
|
||||
dest = (my_dest_ptr) cinfo->dest;
|
||||
dest->pub.init_destination = JPEGInitDestination;
|
||||
dest->pub.empty_output_buffer = JPEGEmptyOutputBuffer;
|
||||
dest->pub.term_destination = JPEGTermDestination;
|
||||
dest->outfile = outfile;
|
||||
dest->size = size;
|
||||
}
|
||||
|
||||
void roq::WriteLossless( void ) {
|
||||
|
||||
word direct;
|
||||
uint directdw;
|
||||
|
||||
if (!dataStuff) {
|
||||
InitRoQPatterns();
|
||||
dataStuff=true;
|
||||
}
|
||||
direct = RoQ_QUAD_JPEG;
|
||||
Write16Word( &direct, RoQFile);
|
||||
|
||||
/* This struct contains the JPEG compression parameters and pointers to
|
||||
* working space (which is allocated as needed by the JPEG library).
|
||||
* It is possible to have several such structures, representing multiple
|
||||
* compression/decompression processes, in existence at once. We refer
|
||||
* to any one struct (and its associated working data) as a "JPEG object".
|
||||
*/
|
||||
struct jpeg_compress_struct cinfo;
|
||||
/* This struct represents a JPEG error handler. It is declared separately
|
||||
* because applications often want to supply a specialized error handler
|
||||
* (see the second half of this file for an example). But here we just
|
||||
* take the easy way out and use the standard error handler, which will
|
||||
* print a message on stderr and call exit() if compression fails.
|
||||
* Note that this struct must live as long as the main JPEG parameter
|
||||
* struct, to avoid dangling-pointer problems.
|
||||
*/
|
||||
struct jpeg_error_mgr jerr;
|
||||
/* More stuff */
|
||||
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
|
||||
int row_stride; /* physical row width in image buffer */
|
||||
byte *out;
|
||||
|
||||
/* Step 1: allocate and initialize JPEG compression object */
|
||||
|
||||
/* We have to set up the error handler first, in case the initialization
|
||||
* step fails. (Unlikely, but it could happen if you are out of memory.)
|
||||
* This routine fills in the contents of struct jerr, and returns jerr's
|
||||
* address which we place into the link field in cinfo.
|
||||
*/
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
/* Now we can initialize the JPEG compression object. */
|
||||
jpeg_create_compress(&cinfo);
|
||||
|
||||
/* Step 2: specify data destination (eg, a file) */
|
||||
/* Note: steps 2 and 3 can be done in either order. */
|
||||
|
||||
/* Here we use the library-supplied code to send compressed data to a
|
||||
* stdio stream. You can also write your own code to do something else.
|
||||
* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
|
||||
* requires it in order to write binary files.
|
||||
*/
|
||||
out = (byte *)Mem_Alloc(image->pixelsWide()*image->pixelsHigh()*4);
|
||||
JPEGDest(&cinfo, out, image->pixelsWide()*image->pixelsHigh()*4);
|
||||
|
||||
/* Step 3: set parameters for compression */
|
||||
|
||||
/* First we supply a description of the input image.
|
||||
* Four fields of the cinfo struct must be filled in:
|
||||
*/
|
||||
cinfo.image_width = image->pixelsWide(); /* image width and height, in pixels */
|
||||
cinfo.image_height = image->pixelsHigh();
|
||||
cinfo.input_components = 4; /* # of color components per pixel */
|
||||
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
|
||||
/* Now use the library's routine to set default compression parameters.
|
||||
* (You must set at least cinfo.in_color_space before calling this,
|
||||
* since the defaults depend on the source color space.)
|
||||
*/
|
||||
jpeg_set_defaults(&cinfo);
|
||||
/* Now you can set any non-default parameters you wish to.
|
||||
* Here we just illustrate the use of quality (quantization table) scaling:
|
||||
*/
|
||||
jpeg_set_quality(&cinfo, paramFile->JpegQuality(), true /* limit to baseline-JPEG values */);
|
||||
|
||||
/* Step 4: Start compressor */
|
||||
|
||||
/* true ensures that we will write a complete interchange-JPEG file.
|
||||
* Pass true unless you are very sure of what you're doing.
|
||||
*/
|
||||
JPEGStartCompress(&cinfo, true);
|
||||
|
||||
/* Step 5: while (scan lines remain to be written) */
|
||||
/* jpeg_write_scanlines(...); */
|
||||
|
||||
/* Here we use the library's state variable cinfo.next_scanline as the
|
||||
* loop counter, so that we don't have to keep track ourselves.
|
||||
* To keep things simple, we pass one scanline per call; you can pass
|
||||
* more if you wish, though.
|
||||
*/
|
||||
row_stride = image->pixelsWide() * 4; /* JSAMPLEs per row in image_buffer */
|
||||
|
||||
byte *pixbuf = image->bitmapData();
|
||||
while (cinfo.next_scanline < cinfo.image_height) {
|
||||
/* jpeg_write_scanlines expects an array of pointers to scanlines.
|
||||
* Here the array is only one element long, but you could pass
|
||||
* more than one scanline at a time if that's more convenient.
|
||||
*/
|
||||
row_pointer[0] = &pixbuf[((cinfo.image_height-1)*row_stride)-cinfo.next_scanline * row_stride];
|
||||
(void) JPEGWriteScanlines(&cinfo, row_pointer, 1);
|
||||
}
|
||||
|
||||
/* Step 6: Finish compression */
|
||||
|
||||
jpeg_finish_compress(&cinfo);
|
||||
/* After finish_compress, we can close the output file. */
|
||||
|
||||
directdw = hackSize;
|
||||
common->Printf("writeLossless: writing %d bytes to RoQ_QUAD_JPEG\n", hackSize);
|
||||
Write32Word( &directdw, RoQFile );
|
||||
direct = 0; // flags
|
||||
Write16Word( &direct, RoQFile );
|
||||
|
||||
RoQFile->Write( out, hackSize );
|
||||
Mem_Free(out);
|
||||
|
||||
/* Step 7: release JPEG compression object */
|
||||
|
||||
/* This is an important step since it will release a good deal of memory. */
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
|
||||
/* And we're done! */
|
||||
encoder->SetPreviousImage( "first frame", image );
|
||||
}
|
||||
|
||||
void roq::InitRoQFile( const char *RoQFilename )
|
||||
{
|
||||
word i;
|
||||
static int finit = 0;
|
||||
|
||||
if (!finit) {
|
||||
finit++;
|
||||
common->Printf("initRoQFile: %s\n", RoQFilename);
|
||||
RoQFile = fileSystem->OpenFileWrite( RoQFilename );
|
||||
// chmod(RoQFilename, S_IREAD|S_IWRITE|S_ISUID|S_ISGID|0070|0007 );
|
||||
if ( !RoQFile ) {
|
||||
common->Error("Unable to open output file %s.\n", RoQFilename);
|
||||
}
|
||||
|
||||
i = RoQ_ID;
|
||||
Write16Word( &i, RoQFile );
|
||||
|
||||
i = 0xffff;
|
||||
Write16Word( &i, RoQFile );
|
||||
Write16Word( &i, RoQFile );
|
||||
|
||||
// to retain exact file format write out 32 for new roq's
|
||||
// on loading this will be noted and converted to 1000 / 30
|
||||
// as with any new sound dump avi demos we need to playback
|
||||
// at the speed the sound engine dumps the audio
|
||||
i = 30; // framerate
|
||||
Write16Word( &i, RoQFile );
|
||||
}
|
||||
roqOutfile = RoQFilename;
|
||||
}
|
||||
|
||||
void roq::InitRoQPatterns( void )
|
||||
{
|
||||
uint j;
|
||||
word direct;
|
||||
|
||||
direct = RoQ_QUAD_INFO;
|
||||
Write16Word( &direct, RoQFile );
|
||||
|
||||
j = 8;
|
||||
|
||||
Write32Word( &j, RoQFile );
|
||||
common->Printf("initRoQPatterns: outputting %d bytes to RoQ_INFO\n", j);
|
||||
direct = image->hasAlpha();
|
||||
if (ParamNoAlpha() == true) direct = 0;
|
||||
|
||||
Write16Word( &direct, RoQFile );
|
||||
|
||||
direct = image->pixelsWide();
|
||||
Write16Word( &direct, RoQFile );
|
||||
direct = image->pixelsHigh();
|
||||
Write16Word( &direct, RoQFile );
|
||||
direct = 8;
|
||||
Write16Word( &direct, RoQFile );
|
||||
direct = 4;
|
||||
Write16Word( &direct, RoQFile );
|
||||
}
|
||||
|
||||
void roq::CloseRoQFile( void )
|
||||
{
|
||||
common->Printf("closeRoQFile: closing RoQ file\n");
|
||||
fileSystem->CloseFile( RoQFile );
|
||||
}
|
||||
|
||||
void roq::WriteHangFrame( void )
|
||||
{
|
||||
uint j;
|
||||
word direct;
|
||||
common->Printf("*******************************************************************\n");
|
||||
direct = RoQ_QUAD_HANG;
|
||||
Write16Word( &direct, RoQFile);
|
||||
j = 0;
|
||||
Write32Word( &j, RoQFile);
|
||||
direct = 0;
|
||||
Write16Word( &direct, RoQFile);
|
||||
}
|
||||
|
||||
void roq::WriteCodeBookToStream( byte *codebook, int csize, word cflags )
|
||||
{
|
||||
uint j;
|
||||
word direct;
|
||||
|
||||
if (!csize) {
|
||||
common->Printf("writeCodeBook: false VQ DATA!!!!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
direct = RoQ_QUAD_CODEBOOK;
|
||||
|
||||
Write16Word( &direct, RoQFile);
|
||||
|
||||
j = csize;
|
||||
|
||||
Write32Word( &j, RoQFile);
|
||||
common->Printf("writeCodeBook: outputting %d bytes to RoQ_QUAD_CODEBOOK\n", j);
|
||||
|
||||
direct = cflags;
|
||||
Write16Word( &direct, RoQFile);
|
||||
|
||||
RoQFile->Write( codebook, j );
|
||||
}
|
||||
|
||||
void roq::WriteCodeBook( byte *codebook )
|
||||
{
|
||||
memcpy( codes, codebook, 4096 );
|
||||
}
|
||||
|
||||
void roq::WriteFrame( quadcel *pquad )
|
||||
{
|
||||
word action, direct;
|
||||
int onCCC, onAction, i, code;
|
||||
uint j;
|
||||
byte *cccList;
|
||||
bool *use2, *use4;
|
||||
int dx,dy,dxMean,dyMean,index2[256],index4[256], dimension;
|
||||
|
||||
cccList = (byte *)Mem_Alloc( numQuadCels * 8); // maximum length
|
||||
use2 = (bool *)Mem_Alloc(256*sizeof(bool));
|
||||
use4 = (bool *)Mem_Alloc(256*sizeof(bool));
|
||||
|
||||
for(i=0;i<256;i++) {
|
||||
use2[i] = false;
|
||||
use4[i] = false;
|
||||
}
|
||||
|
||||
action = 0;
|
||||
j = onAction = 0;
|
||||
onCCC = 2; // onAction going to go at zero
|
||||
|
||||
dxMean = encoder->MotMeanX();
|
||||
dyMean = encoder->MotMeanY();
|
||||
|
||||
if (image->hasAlpha()) dimension = 10; else dimension = 6;
|
||||
|
||||
for (i=0; i<numQuadCels; i++) {
|
||||
if ( pquad[i].size && pquad[i].size < 16 ) {
|
||||
switch( pquad[i].status ) {
|
||||
case SLD:
|
||||
use4[pquad[i].patten[0]] = true;
|
||||
use2[codes[dimension*256+(pquad[i].patten[0]*4)+0]] = true;
|
||||
use2[codes[dimension*256+(pquad[i].patten[0]*4)+1]] = true;
|
||||
use2[codes[dimension*256+(pquad[i].patten[0]*4)+2]] = true;
|
||||
use2[codes[dimension*256+(pquad[i].patten[0]*4)+3]] = true;
|
||||
break;
|
||||
case PAT:
|
||||
use4[pquad[i].patten[0]] = true;
|
||||
use2[codes[dimension*256+(pquad[i].patten[0]*4)+0]] = true;
|
||||
use2[codes[dimension*256+(pquad[i].patten[0]*4)+1]] = true;
|
||||
use2[codes[dimension*256+(pquad[i].patten[0]*4)+2]] = true;
|
||||
use2[codes[dimension*256+(pquad[i].patten[0]*4)+3]] = true;
|
||||
break;
|
||||
case CCC:
|
||||
use2[pquad[i].patten[1]] = true;
|
||||
use2[pquad[i].patten[2]] = true;
|
||||
use2[pquad[i].patten[3]] = true;
|
||||
use2[pquad[i].patten[4]] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!dataStuff) {
|
||||
dataStuff=true;
|
||||
InitRoQPatterns();
|
||||
if (image->hasAlpha()) i = 3584; else i = 2560;
|
||||
WriteCodeBookToStream( codes, i, 0 );
|
||||
for(i=0;i<256;i++) {
|
||||
index2[i] = i;
|
||||
index4[i] = i;
|
||||
}
|
||||
} else {
|
||||
j = 0;
|
||||
for(i=0;i<256;i++) {
|
||||
if (use2[i]) {
|
||||
index2[i] = j;
|
||||
for(dx=0;dx<dimension;dx++) cccList[j*dimension+dx] = codes[i*dimension+dx];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
code = j*dimension;
|
||||
direct = j;
|
||||
common->Printf("writeFrame: really used %d 2x2 cels\n", j);
|
||||
j = 0;
|
||||
for(i=0;i<256;i++) {
|
||||
if (use4[i]) {
|
||||
index4[i] = j;
|
||||
for(dx=0;dx<4;dx++) cccList[j*4+code+dx] = index2[codes[i*4+(dimension*256)+dx]];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
code += j*4;
|
||||
direct = (direct<<8) + j;
|
||||
common->Printf("writeFrame: really used %d 4x4 cels\n", j);
|
||||
if (image->hasAlpha()) i = 3584; else i = 2560;
|
||||
if ( code == i || j == 256) {
|
||||
WriteCodeBookToStream( codes, i, 0 );
|
||||
} else {
|
||||
WriteCodeBookToStream( cccList, code, direct );
|
||||
}
|
||||
}
|
||||
|
||||
action = 0;
|
||||
j = onAction = 0;
|
||||
|
||||
for (i=0; i<numQuadCels; i++) {
|
||||
if ( pquad[i].size && pquad[i].size < 16 ) {
|
||||
code = -1;
|
||||
switch( pquad[i].status ) {
|
||||
case DEP:
|
||||
code = 3;
|
||||
break;
|
||||
case SLD:
|
||||
code = 2;
|
||||
cccList[onCCC++] = index4[pquad[i].patten[0]];
|
||||
break;
|
||||
case MOT:
|
||||
code = 0;
|
||||
break;
|
||||
case FCC:
|
||||
code = 1;
|
||||
dx = ((pquad[i].domain >> 8 )) - 128 - dxMean + 8;
|
||||
dy = ((pquad[i].domain & 0xff)) - 128 - dyMean + 8;
|
||||
if (dx>15 || dx<0 || dy>15 || dy<0 ) {
|
||||
common->Error("writeFrame: FCC error %d,%d mean %d,%d at %d,%d,%d rmse %f\n", dx,dy, dxMean, dyMean,pquad[i].xat,pquad[i].yat,pquad[i].size, pquad[i].snr[FCC] );
|
||||
}
|
||||
cccList[onCCC++] = (dx<<4)+dy;
|
||||
break;
|
||||
case PAT:
|
||||
code = 2;
|
||||
cccList[onCCC++] = index4[pquad[i].patten[0]];
|
||||
break;
|
||||
case CCC:
|
||||
code = 3;
|
||||
cccList[onCCC++] = index2[pquad[i].patten[1]];
|
||||
cccList[onCCC++] = index2[pquad[i].patten[2]];
|
||||
cccList[onCCC++] = index2[pquad[i].patten[3]];
|
||||
cccList[onCCC++] = index2[pquad[i].patten[4]];
|
||||
break;
|
||||
case DEAD:
|
||||
common->Error("dead cels in picture\n");
|
||||
break;
|
||||
}
|
||||
if (code == -1) {
|
||||
common->Error( "writeFrame: an error occurred writing the frame\n");
|
||||
}
|
||||
|
||||
action = (action<<2)|code;
|
||||
j++;
|
||||
if (j == 8) {
|
||||
j = 0;
|
||||
cccList[onAction+0] = (action & 0xff);
|
||||
cccList[onAction+1] = ((action >> 8) & 0xff);
|
||||
onAction = onCCC;
|
||||
onCCC += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (j) {
|
||||
action <<= ((8-j)*2);
|
||||
cccList[onAction+0] = (action & 0xff);
|
||||
cccList[onAction+1] = ((action >> 8) & 0xff);
|
||||
}
|
||||
|
||||
direct = RoQ_QUAD_VQ;
|
||||
|
||||
Write16Word( &direct, RoQFile);
|
||||
|
||||
j = onCCC;
|
||||
Write32Word( &j, RoQFile);
|
||||
|
||||
direct = dyMean;
|
||||
direct &= 0xff;
|
||||
direct += (dxMean<<8); // flags
|
||||
|
||||
Write16Word( &direct, RoQFile);
|
||||
|
||||
common->Printf("writeFrame: outputting %d bytes to RoQ_QUAD_VQ\n", j);
|
||||
|
||||
previousSize = j;
|
||||
|
||||
RoQFile->Write( cccList, onCCC );
|
||||
|
||||
Mem_Free( cccList );
|
||||
Mem_Free( use2 );
|
||||
Mem_Free( use4 );
|
||||
}
|
||||
|
||||
//
|
||||
// load a frame, create a window (if neccesary) and display the frame
|
||||
//
|
||||
void roq::LoadAndDisplayImage( const char * filename )
|
||||
{
|
||||
if (image) delete image;
|
||||
|
||||
common->Printf("loadAndDisplayImage: %s\n", filename);
|
||||
|
||||
currentFile = filename;
|
||||
|
||||
image = new NSBitmapImageRep( filename );
|
||||
|
||||
numQuadCels = ((image->pixelsWide() & 0xfff0)*(image->pixelsHigh() & 0xfff0))/(MINSIZE*MINSIZE);
|
||||
numQuadCels += numQuadCels/4 + numQuadCels/16;
|
||||
|
||||
// if (paramFile->deltaFrames] == true && cleared == false && [image isPlanar] == false) {
|
||||
// cleared = true;
|
||||
// imageData = [image data];
|
||||
// memset( imageData, 0, image->pixelsWide()*image->pixelsHigh()*[image samplesPerPixel]);
|
||||
// }
|
||||
|
||||
if (!quietMode) common->Printf("loadAndDisplayImage: %dx%d\n", image->pixelsWide(), image->pixelsHigh());
|
||||
}
|
||||
|
||||
void roq::MarkQuadx( int xat, int yat, int size, float cerror, int choice ) {
|
||||
}
|
||||
|
||||
NSBitmapImageRep* roq::CurrentImage( void )
|
||||
{
|
||||
return image;
|
||||
}
|
||||
|
||||
int roq::NumberOfFrames( void ) {
|
||||
return numberOfFrames;
|
||||
}
|
||||
|
||||
void RoQFileEncode_f( const idCmdArgs &args ) {
|
||||
if ( args.Argc() != 2 ) {
|
||||
common->Printf( "Usage: roq <paramfile>\n" );
|
||||
return;
|
||||
}
|
||||
theRoQ = new roq;
|
||||
int startMsec = Sys_Milliseconds();
|
||||
theRoQ->EncodeStream( args.Argv( 1 ) );
|
||||
int stopMsec = Sys_Milliseconds();
|
||||
common->Printf( "total encoding time: %i second\n", ( stopMsec - startMsec ) / 1000 );
|
||||
|
||||
}
|
||||
135
neo/tools/compilers/roqvq/roq.h
Normal file
135
neo/tools/compilers/roqvq/roq.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 GPL Source Code
|
||||
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
|
||||
|
||||
Doom 3 Source Code 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#ifndef __roq_h__
|
||||
#define __roq_h__
|
||||
|
||||
#include "gdefs.h"
|
||||
#include "roqParam.h"
|
||||
#include "quaddefs.h"
|
||||
#define JPEG_INTERNALS
|
||||
extern "C" {
|
||||
#include "../../../renderer/jpeg-6/jpeglib.h"
|
||||
}
|
||||
#pragma once
|
||||
|
||||
class codec;
|
||||
class roqParam;
|
||||
|
||||
class NSBitmapImageRep {
|
||||
public:
|
||||
|
||||
NSBitmapImageRep( void );
|
||||
NSBitmapImageRep( const char *filename );
|
||||
NSBitmapImageRep( int wide, int high );
|
||||
~NSBitmapImageRep();
|
||||
|
||||
NSBitmapImageRep & operator=( const NSBitmapImageRep &a );
|
||||
|
||||
int samplesPerPixel( void );
|
||||
int pixelsWide( void );
|
||||
int pixelsHigh( void );
|
||||
byte * bitmapData( void );
|
||||
bool hasAlpha( void );
|
||||
bool isPlanar( void );
|
||||
|
||||
private:
|
||||
|
||||
byte * bmap;
|
||||
int width;
|
||||
int height;
|
||||
ID_TIME_T timestamp;
|
||||
|
||||
};
|
||||
|
||||
class roq {
|
||||
public:
|
||||
roq();
|
||||
~roq();
|
||||
|
||||
void WriteLossless( void );
|
||||
void LoadAndDisplayImage( const char *filename );
|
||||
void CloseRoQFile( bool which );
|
||||
void InitRoQFile( const char *roqFilename );
|
||||
void InitRoQPatterns( void );
|
||||
void EncodeStream( const char *paramInputFile );
|
||||
void EncodeQuietly( bool which );
|
||||
bool IsQuiet( void );
|
||||
bool IsLastFrame( void );
|
||||
NSBitmapImageRep * CurrentImage( void );
|
||||
void MarkQuadx( int xat, int yat, int size, float cerror, int choice );
|
||||
void WritePuzzleFrame( quadcel *pquad );
|
||||
void WriteFrame( quadcel *pquad );
|
||||
void WriteCodeBook( byte *codebook );
|
||||
void WwriteCodeBookToStream( byte *codes, int csize, word cflags );
|
||||
int PreviousFrameSize( void );
|
||||
bool MakingVideo( void );
|
||||
bool ParamNoAlpha( void );
|
||||
bool SearchType( void );
|
||||
bool HasSound( void );
|
||||
const char * CurrentFilename( void );
|
||||
int NormalFrameSize( void );
|
||||
int FirstFrameSize( void );
|
||||
bool Scaleable( void );
|
||||
void WriteHangFrame( void );
|
||||
int NumberOfFrames( void );
|
||||
private:
|
||||
void Write16Word( word *aWord, idFile *stream );
|
||||
void Write32Word( unsigned int *aWord, idFile *stream );
|
||||
int SizeFile( idFile *ftosize );
|
||||
void CloseRoQFile( void );
|
||||
void WriteCodeBookToStream( byte *codebook, int csize, word cflags );
|
||||
|
||||
static void JPEGInitDestination( j_compress_ptr cinfo );
|
||||
static boolean JPEGEmptyOutputBuffer( j_compress_ptr cinfo );
|
||||
static void JPEGTermDestination( j_compress_ptr cinfo );
|
||||
|
||||
void JPEGStartCompress( j_compress_ptr cinfo, bool write_all_tables );
|
||||
JDIMENSION JPEGWriteScanlines( j_compress_ptr cinfo, JSAMPARRAY scanlines, JDIMENSION num_lines );
|
||||
void JPEGDest( j_compress_ptr cinfo, byte* outfile, int size );
|
||||
void JPEGSave( char * filename, int quality, int image_width, int image_height, unsigned char *image_buffer );
|
||||
|
||||
codec * encoder;
|
||||
roqParam * paramFile;
|
||||
|
||||
idFile * RoQFile;
|
||||
NSBitmapImageRep * image;
|
||||
int numQuadCels;
|
||||
bool quietMode;
|
||||
bool lastFrame;
|
||||
idStr roqOutfile;
|
||||
idStr currentFile;
|
||||
int numberOfFrames;
|
||||
int previousSize;
|
||||
byte codes[4096];
|
||||
bool dataStuff;
|
||||
|
||||
};
|
||||
|
||||
extern roq *theRoQ; // current roq
|
||||
|
||||
#endif /* !__roq_h__ */
|
||||
933
neo/tools/compilers/roqvq/roq.m
Normal file
933
neo/tools/compilers/roqvq/roq.m
Normal file
@@ -0,0 +1,933 @@
|
||||
|
||||
#import "roq.h"
|
||||
#import "codec.h"
|
||||
|
||||
#ifdef __MACOS__
|
||||
|
||||
blah
|
||||
|
||||
#endif
|
||||
|
||||
@implementation roq
|
||||
|
||||
|
||||
- init
|
||||
{
|
||||
cWindow = eWindow = sWindow = 0;
|
||||
image = 0;
|
||||
quietMode = NO;
|
||||
encoder = 0;
|
||||
previousSize = 0;
|
||||
lastFrame = NO;
|
||||
codes = malloc( 4*1024 );
|
||||
dataStuff=NO;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
free( codes );
|
||||
|
||||
if (image) [image dealloc];
|
||||
if (encoder) [encoder dealloc];
|
||||
return;
|
||||
}
|
||||
|
||||
- encodeQuietly:(BOOL)which
|
||||
{
|
||||
quietMode = which;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)isQuiet
|
||||
{
|
||||
return quietMode;
|
||||
}
|
||||
|
||||
- (BOOL)isLastFrame
|
||||
{
|
||||
return lastFrame;
|
||||
}
|
||||
|
||||
- (BOOL)scaleable
|
||||
{
|
||||
return [paramFileId isScaleable];
|
||||
}
|
||||
|
||||
- (BOOL)paramNoAlpha
|
||||
{
|
||||
return [paramFileId noAlpha];
|
||||
}
|
||||
|
||||
- (BOOL)makingVideo
|
||||
{
|
||||
return YES; //[paramFileId timecode];
|
||||
}
|
||||
|
||||
- (BOOL)searchType
|
||||
{
|
||||
return [paramFileId searchType];
|
||||
}
|
||||
|
||||
- (BOOL)hasSound
|
||||
{
|
||||
return [paramFileId hasSound];
|
||||
}
|
||||
|
||||
- (int)previousFrameSize
|
||||
{
|
||||
return previousSize;
|
||||
}
|
||||
|
||||
-(int)firstFrameSize
|
||||
{
|
||||
return [paramFileId firstFrameSize];
|
||||
}
|
||||
|
||||
-(int)normalFrameSize
|
||||
{
|
||||
return [paramFileId normalFrameSize];
|
||||
}
|
||||
|
||||
- (char *)currentFilename
|
||||
{
|
||||
return currentFile;
|
||||
}
|
||||
|
||||
-encodeStream: (id)paramInputFile
|
||||
{
|
||||
int onFrame;
|
||||
char f0[MAXPATHLEN], f1[MAXPATHLEN], f2[MAXPATHLEN];
|
||||
int morestuff;
|
||||
|
||||
onFrame = 1;
|
||||
|
||||
encoder = [[codec alloc] init: self];
|
||||
numberOfFrames = [paramInputFile numberOfFrames];
|
||||
paramFileId = paramInputFile;
|
||||
|
||||
if ([paramInputFile noAlpha]==YES) printf("encodeStream: eluding alpha\n");
|
||||
|
||||
f0[0] = 0;
|
||||
strcpy( f1, [paramInputFile getNextImageFilename]);
|
||||
if (( [paramInputFile moreFrames] == YES )) strcpy( f2, [paramInputFile getNextImageFilename]);
|
||||
morestuff = numberOfFrames;
|
||||
|
||||
while( morestuff ) {
|
||||
[self loadAndDisplayImage: f1];
|
||||
|
||||
if (onFrame==1 && ([image hadAlpha]==NO || [paramInputFile noAlpha]==YES) && ![self makingVideo] && ![self scaleable]) {
|
||||
[encoder sparseEncode: self];
|
||||
// [self writeLossless];
|
||||
} else {
|
||||
if (!strcmp( f0, f1 ) && strcmp( f1, f2) ) {
|
||||
[self writeHangFrame];
|
||||
} else {
|
||||
[encoder sparseEncode: self];
|
||||
}
|
||||
}
|
||||
|
||||
onFrame++;
|
||||
strcpy( f0, f1 );
|
||||
strcpy( f1, f2 );
|
||||
if ([paramInputFile moreFrames] == YES) strcpy( f2, [paramInputFile getNextImageFilename]);
|
||||
morestuff--;
|
||||
}
|
||||
|
||||
if (numberOfFrames != 1) {
|
||||
if ([image hadAlpha] && [paramInputFile noAlpha]==NO) {
|
||||
lastFrame = YES;
|
||||
[encoder sparseEncode: self];
|
||||
} else {
|
||||
[self writeLossless];
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- write16Word:(word *)aWord to:(FILE *)stream
|
||||
{
|
||||
byte a, b;
|
||||
|
||||
a = *aWord & 0xff;
|
||||
b = *aWord >> 8;
|
||||
|
||||
fputc( a, stream );
|
||||
fputc( b, stream );
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- write32Word:( unsigned int *)aWord to:(FILE *)stream
|
||||
{
|
||||
byte a, b, c, d;
|
||||
|
||||
a = *aWord & 0xff;
|
||||
b = (*aWord >> 8) & 0xff;
|
||||
c = (*aWord >> 16) & 0xff;
|
||||
d = (*aWord >> 24) & 0xff;
|
||||
|
||||
fputc( a, stream );
|
||||
fputc( b, stream );
|
||||
fputc( c, stream );
|
||||
fputc( d, stream );
|
||||
return self;
|
||||
}
|
||||
|
||||
-(int)sizeFile:(FILE *)ftosize;
|
||||
{
|
||||
long int fat, fend;
|
||||
fat = ftell(ftosize);
|
||||
fseek( ftosize, 0, SEEK_END );
|
||||
fend = ftell(ftosize);
|
||||
fseek( ftosize, fat, SEEK_SET);
|
||||
return (fend);
|
||||
}
|
||||
|
||||
- convertPlanertoPacked
|
||||
{
|
||||
byte *iPlane[5], *newdata, *olddata;
|
||||
int x,y,index, sample, pixelsWide, pixelsHigh;
|
||||
TByteBitmapImageRep *newImage;
|
||||
|
||||
pixelsWide = [image pixelsWide];
|
||||
pixelsHigh = [image pixelsHigh];
|
||||
|
||||
printf("convertPlanertoPacked: converting\n");
|
||||
|
||||
newImage = [[TByteBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
|
||||
pixelsWide: pixelsWide
|
||||
pixelsHigh: pixelsHigh
|
||||
bitsPerSample: 8
|
||||
samplesPerPixel: 4
|
||||
hasAlpha: YES
|
||||
isPlanar: NO
|
||||
colorSpaceName: NSCalibratedRGBColorSpace
|
||||
bytesPerRow: 0
|
||||
bitsPerPixel: 0];
|
||||
|
||||
newdata = [newImage bitmapData];
|
||||
index = 0;
|
||||
|
||||
if ([image isPlanar]) {
|
||||
[image getBitmapDataPlanes: iPlane];
|
||||
for(y=0;y<pixelsHigh;y++) {
|
||||
for(x=0;x<pixelsWide;x++) {
|
||||
newdata[index++] = iPlane[0][y*pixelsWide+x];
|
||||
newdata[index++] = iPlane[1][y*pixelsWide+x];
|
||||
newdata[index++] = iPlane[2][y*pixelsWide+x];
|
||||
if ([image hasAlpha]) {
|
||||
newdata[index++] = iPlane[3][y*pixelsWide+x];
|
||||
} else {
|
||||
newdata[index++] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sample = 0;
|
||||
olddata = [image bitmapData];
|
||||
for(y=0;y<pixelsHigh;y++) {
|
||||
for(x=0;x<pixelsWide;x++) {
|
||||
newdata[index++] = olddata[sample++];
|
||||
newdata[index++] = olddata[sample++];
|
||||
newdata[index++] = olddata[sample++];
|
||||
if ([image hasAlpha]) {
|
||||
newdata[index++] = olddata[sample++];
|
||||
} else {
|
||||
newdata[index++] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[image dealloc];
|
||||
image = newImage;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- writeLossless
|
||||
{
|
||||
word direct;
|
||||
unsigned int j;
|
||||
char tempFile[MAXPATHLEN];
|
||||
FILE *ftemp;
|
||||
byte *buffer;
|
||||
int res, mess;
|
||||
|
||||
[self convertPlanertoPacked];
|
||||
if (!dataStuff) {
|
||||
[self initRoQPatterns];
|
||||
dataStuff=YES;
|
||||
}
|
||||
direct = RoQ_QUAD_JPEG;
|
||||
[self write16Word: &direct to: RoQFile];
|
||||
sprintf(tempFile, "%s.jpg",[paramFileId roqTempFilename]);
|
||||
|
||||
[image writeJFIF:tempFile quality: [paramFileId jpegQuality]];
|
||||
|
||||
ftemp = fopen(tempFile, "rb");
|
||||
if (!ftemp) { fprintf(stderr, "Could not open temp file\n"); exit(1); }
|
||||
j = [self sizeFile: ftemp];
|
||||
printf("writeLossless: writing %d bytes to RoQ_QUAD_JPEG\n", j);
|
||||
[self write32Word: &j to: RoQFile];
|
||||
direct = 0; // flags
|
||||
[self write16Word: &direct to: RoQFile];
|
||||
|
||||
buffer = malloc( 16384 );
|
||||
do {
|
||||
res = fread( buffer, 1, 16384, ftemp);
|
||||
mess = fwrite( buffer, 1, res, RoQFile );
|
||||
if (res != mess) { fprintf(stderr, "Could not write to output stream\n"); exit(1); }
|
||||
} while ( res == 16384 );
|
||||
free( buffer );
|
||||
fclose(ftemp);
|
||||
[encoder setPreviousImage: tempFile from: image parent: self];
|
||||
remove( tempFile );
|
||||
fflush( RoQFile );
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- initRoQFile:(const char *)RoQFilename
|
||||
{
|
||||
word i;
|
||||
static int finit = 0;
|
||||
|
||||
if (!finit) {
|
||||
finit++;
|
||||
printf("initRoQFile: %s\n", RoQFilename);
|
||||
RoQFile = fopen( RoQFilename, "w" );
|
||||
// chmod(RoQFilename, S_IREAD|S_IWRITE|S_ISUID|S_ISGID|0070|0007 );
|
||||
if (!RoQFile) {
|
||||
fprintf(stderr,"Unable to open output file %s.\n", RoQFilename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
i = RoQ_ID;
|
||||
[self write16Word: &i to: RoQFile];
|
||||
|
||||
i = 0xffff;
|
||||
[self write16Word: &i to: RoQFile];
|
||||
[self write16Word: &i to: RoQFile];
|
||||
|
||||
i = 24; // framerate
|
||||
[self write16Word: &i to: RoQFile];
|
||||
fflush( RoQFile );
|
||||
}
|
||||
strcpy( roqOutfile, RoQFilename );
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- initRoQPatterns
|
||||
{
|
||||
int j;
|
||||
word direct;
|
||||
|
||||
direct = RoQ_QUAD_INFO;
|
||||
[self write16Word: &direct to: RoQFile];
|
||||
|
||||
j = 8;
|
||||
|
||||
[self write32Word: &j to: RoQFile];
|
||||
printf("initRoQPatterns: outputting %d bytes to RoQ_INFO\n", j);
|
||||
direct = [image hadAlpha];
|
||||
if ([self paramNoAlpha] == YES) direct = 0;
|
||||
|
||||
[self write16Word: &direct to: RoQFile];
|
||||
|
||||
direct = [image pixelsWide];
|
||||
[self write16Word: &direct to: RoQFile];
|
||||
direct = [image pixelsHigh];
|
||||
[self write16Word: &direct to: RoQFile];
|
||||
direct = 8;
|
||||
[self write16Word: &direct to: RoQFile];
|
||||
direct = 4;
|
||||
[self write16Word: &direct to: RoQFile];
|
||||
|
||||
fflush( RoQFile );
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- closeRoQFile
|
||||
{
|
||||
fflush( RoQFile );
|
||||
printf("closeRoQFile: closing RoQ file\n");
|
||||
fclose( RoQFile );
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- writeHangFrame
|
||||
{
|
||||
int j;
|
||||
word direct;
|
||||
printf("*******************************************************************\n");
|
||||
direct = RoQ_QUAD_HANG;
|
||||
[self write16Word: &direct to: RoQFile];
|
||||
j = 0;
|
||||
[self write32Word: &j to: RoQFile];
|
||||
direct = 0;
|
||||
[self write16Word: &direct to: RoQFile];
|
||||
return self;
|
||||
}
|
||||
|
||||
- writeCodeBookToStream: (byte *)codebook size: (int)csize flags: (word)cflags
|
||||
{
|
||||
int j;
|
||||
word direct;
|
||||
|
||||
if (!csize) {
|
||||
printf("writeCodeBook: NO VQ DATA!!!!\n");
|
||||
return self;
|
||||
}
|
||||
|
||||
direct = RoQ_QUAD_CODEBOOK;
|
||||
|
||||
[self write16Word: &direct to: RoQFile];
|
||||
|
||||
j = csize;
|
||||
|
||||
[self write32Word: &j to: RoQFile];
|
||||
printf("writeCodeBook: outputting %d bytes to RoQ_QUAD_CODEBOOK\n", j);
|
||||
|
||||
direct = cflags;
|
||||
[self write16Word: &direct to: RoQFile];
|
||||
|
||||
fwrite( codebook, j, 1, RoQFile);
|
||||
|
||||
fflush( RoQFile );
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- writeCodeBook: (byte *)codebook
|
||||
{
|
||||
memcpy( codes, codebook, 4096 );
|
||||
return self;
|
||||
}
|
||||
|
||||
- writeFrame:(quadcel *)pquad
|
||||
{
|
||||
word action, direct;
|
||||
int onCCC, onAction, i, j, code;
|
||||
byte *cccList;
|
||||
BOOL *use2, *use4;
|
||||
int dx,dy,dxMean,dyMean,index2[256],index4[256], dimension;
|
||||
|
||||
cccList = malloc( numQuadCels * 8); // maximum length
|
||||
use2 = malloc(256*sizeof(BOOL));
|
||||
use4 = malloc(256*sizeof(BOOL));
|
||||
|
||||
for(i=0;i<256;i++) {
|
||||
use2[i] = NO;
|
||||
use4[i] = NO;
|
||||
}
|
||||
|
||||
action = 0;
|
||||
j = onAction = 0;
|
||||
onCCC = 2; // onAction going to go at zero
|
||||
|
||||
dxMean = [encoder motMeanX];
|
||||
dyMean = [encoder motMeanY];
|
||||
|
||||
if ([image hadAlpha]) dimension = 10; else dimension = 6;
|
||||
|
||||
for (i=0; i<numQuadCels; i++) {
|
||||
if ( pquad[i].size && pquad[i].size < 16 ) {
|
||||
switch( pquad[i].status ) {
|
||||
case SLD:
|
||||
use4[pquad[i].patten[0]] = YES;
|
||||
use2[codes[dimension*256+(pquad[i].patten[0]*4)+0]] = YES;
|
||||
use2[codes[dimension*256+(pquad[i].patten[0]*4)+1]] = YES;
|
||||
use2[codes[dimension*256+(pquad[i].patten[0]*4)+2]] = YES;
|
||||
use2[codes[dimension*256+(pquad[i].patten[0]*4)+3]] = YES;
|
||||
break;
|
||||
case PAT:
|
||||
use4[pquad[i].patten[0]] = YES;
|
||||
use2[codes[dimension*256+(pquad[i].patten[0]*4)+0]] = YES;
|
||||
use2[codes[dimension*256+(pquad[i].patten[0]*4)+1]] = YES;
|
||||
use2[codes[dimension*256+(pquad[i].patten[0]*4)+2]] = YES;
|
||||
use2[codes[dimension*256+(pquad[i].patten[0]*4)+3]] = YES;
|
||||
break;
|
||||
case CCC:
|
||||
use2[pquad[i].patten[1]] = YES;
|
||||
use2[pquad[i].patten[2]] = YES;
|
||||
use2[pquad[i].patten[3]] = YES;
|
||||
use2[pquad[i].patten[4]] = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!dataStuff) {
|
||||
dataStuff=YES;
|
||||
[self initRoQPatterns];
|
||||
if ([image hadAlpha]) i = 3584; else i = 2560;
|
||||
[self writeCodeBookToStream: codes size: i flags: 0];
|
||||
for(i=0;i<256;i++) {
|
||||
index2[i] = i;
|
||||
index4[i] = i;
|
||||
}
|
||||
} else {
|
||||
j = 0;
|
||||
for(i=0;i<256;i++) {
|
||||
if (use2[i]) {
|
||||
index2[i] = j;
|
||||
for(dx=0;dx<dimension;dx++) cccList[j*dimension+dx] = codes[i*dimension+dx];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
code = j*dimension;
|
||||
direct = j;
|
||||
printf("writeFrame: really used %d 2x2 cels\n", j);
|
||||
j = 0;
|
||||
for(i=0;i<256;i++) {
|
||||
if (use4[i]) {
|
||||
index4[i] = j;
|
||||
for(dx=0;dx<4;dx++) cccList[j*4+code+dx] = index2[codes[i*4+(dimension*256)+dx]];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
code += j*4;
|
||||
direct = (direct<<8) + j;
|
||||
printf("writeFrame: really used %d 4x4 cels\n", j);
|
||||
if ([image hadAlpha]) i = 3584; else i = 2560;
|
||||
if ( code == i || j == 256) {
|
||||
[self writeCodeBookToStream: codes size: i flags: 0];
|
||||
} else {
|
||||
[self writeCodeBookToStream: cccList size: code flags: direct];
|
||||
}
|
||||
}
|
||||
|
||||
action = 0;
|
||||
j = onAction = 0;
|
||||
|
||||
for (i=0; i<numQuadCels; i++) {
|
||||
if ( pquad[i].size && pquad[i].size < 16 ) {
|
||||
code = -1;
|
||||
switch( pquad[i].status ) {
|
||||
case DEP:
|
||||
code = 3;
|
||||
break;
|
||||
case SLD:
|
||||
code = 2;
|
||||
cccList[onCCC++] = index4[pquad[i].patten[0]];
|
||||
break;
|
||||
case MOT:
|
||||
code = 0;
|
||||
break;
|
||||
case FCC:
|
||||
code = 1;
|
||||
dx = ((pquad[i].domain >> 8 )) - 128 - dxMean + 8;
|
||||
dy = ((pquad[i].domain & 0xff)) - 128 - dyMean + 8;
|
||||
if (dx>15 || dx<0 || dy>15 || dy<0 ) {
|
||||
printf("writeFrame: FCC error %d,%d mean %d,%d at %d,%d,%d rmse %f\n", dx,dy, dxMean, dyMean,pquad[i].xat,pquad[i].yat,pquad[i].size, pquad[i].snr[FCC] );
|
||||
exit(1);
|
||||
}
|
||||
cccList[onCCC++] = (dx<<4)+dy;
|
||||
break;
|
||||
case PAT:
|
||||
code = 2;
|
||||
cccList[onCCC++] = index4[pquad[i].patten[0]];
|
||||
break;
|
||||
case CCC:
|
||||
code = 3;
|
||||
cccList[onCCC++] = index2[pquad[i].patten[1]];
|
||||
cccList[onCCC++] = index2[pquad[i].patten[2]];
|
||||
cccList[onCCC++] = index2[pquad[i].patten[3]];
|
||||
cccList[onCCC++] = index2[pquad[i].patten[4]];
|
||||
break;
|
||||
case DEAD:
|
||||
fprintf(stderr,"dead cels in picture\n");
|
||||
break;
|
||||
}
|
||||
if (code == -1) {
|
||||
fprintf(stderr, "writeFrame: an error occurred writing the frame\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
action = (action<<2)|code;
|
||||
j++;
|
||||
if (j == 8) {
|
||||
j = 0;
|
||||
cccList[onAction+0] = (action & 0xff);
|
||||
cccList[onAction+1] = ((action >> 8) & 0xff);
|
||||
onAction = onCCC;
|
||||
onCCC += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (j) {
|
||||
action <<= ((8-j)*2);
|
||||
cccList[onAction+0] = (action & 0xff);
|
||||
cccList[onAction+1] = ((action >> 8) & 0xff);
|
||||
}
|
||||
|
||||
direct = RoQ_QUAD_VQ;
|
||||
|
||||
[self write16Word: &direct to: RoQFile];
|
||||
|
||||
j = onCCC;
|
||||
[self write32Word: &j to: RoQFile];
|
||||
|
||||
direct = dyMean;
|
||||
direct &= 0xff;
|
||||
direct += (dxMean<<8); // flags
|
||||
|
||||
[self write16Word: &direct to: RoQFile];
|
||||
|
||||
printf("writeFrame: outputting %d bytes to RoQ_QUAD_VQ\n", j);
|
||||
|
||||
previousSize = j;
|
||||
|
||||
fwrite( cccList, onCCC, 1, RoQFile );
|
||||
|
||||
fflush( RoQFile );
|
||||
|
||||
free( cccList );
|
||||
free( use2 );
|
||||
free( use4 );
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- writePuzzleFrame:(quadcel *)pquad
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
- (TByteBitmapImageRep *)scaleImage: (TByteBitmapImageRep *)toscale
|
||||
{
|
||||
int newx, newy,x,y,s,linesize;
|
||||
TByteBitmapImageRep *newImage;
|
||||
unsigned char *i0, *i1;
|
||||
int newv;
|
||||
|
||||
newx = 288;
|
||||
|
||||
if ([toscale pixelsHigh] == 160) {
|
||||
newy = 320;
|
||||
} else {
|
||||
newy = [toscale pixelsHigh];
|
||||
}
|
||||
newImage = [[TByteBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
|
||||
pixelsWide: newx
|
||||
pixelsHigh: newy
|
||||
bitsPerSample: 8
|
||||
samplesPerPixel: 4
|
||||
hasAlpha: YES
|
||||
isPlanar: NO
|
||||
colorSpaceName: NSCalibratedRGBColorSpace
|
||||
bytesPerRow: 0
|
||||
bitsPerPixel: 0];
|
||||
|
||||
i0 = [toscale bitmapData];
|
||||
i1 = [newImage bitmapData];
|
||||
linesize = [toscale pixelsWide]*4;
|
||||
|
||||
for(y=0; y<newy; y++) {
|
||||
for(x=0; x<320; x++) {
|
||||
if (x>=16 && x<304) {
|
||||
for(s=0;s<4;s++) {
|
||||
if ([toscale pixelsHigh] == 160) {
|
||||
newv = i0[(x*2+0)*4+(y>>1)*linesize+s];
|
||||
newv += i0[(x*2+1)*4+(y>>1)*linesize+s];
|
||||
newv += i0[(x*2+0)*4+((y>>1)+1)*linesize+s];
|
||||
newv += i0[(x*2+1)*4+((y>>1)+1)*linesize+s];
|
||||
newv = newv/4;
|
||||
} else {
|
||||
newv = i0[(x*2+0)*4+y*linesize+s];
|
||||
newv += i0[(x*2+1)*4+y*linesize+s];
|
||||
newv = newv/2;
|
||||
}
|
||||
i1[(x-16)*4+y*(288*4)+s] = newv;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (newImage);
|
||||
}
|
||||
|
||||
//
|
||||
// load a frame, create a window (if neccesary) and display the frame
|
||||
//
|
||||
- loadAndDisplayImage: (const char *) filename
|
||||
{
|
||||
NSRect cRect;
|
||||
char *secondFilename,firstFilename[MAXPATHLEN+1];
|
||||
id image1;
|
||||
NSSize newSize;
|
||||
// unsigned char *imageData;
|
||||
// static BOOL cleared = NO;
|
||||
|
||||
if (image) [image dealloc];
|
||||
|
||||
printf("loadAndDisplayImage: %s\n", filename);
|
||||
|
||||
strcpy( currentFile, filename );
|
||||
|
||||
image = [TByteBitmapImageRep alloc];
|
||||
if (!(secondFilename= strchr(filename,'\n'))) { //one filename, no compositing
|
||||
[image initFromFile: filename ];
|
||||
}
|
||||
else {
|
||||
strncpy(firstFilename,filename,secondFilename-filename);
|
||||
firstFilename[secondFilename-filename]='\0';
|
||||
secondFilename++;//point past the \n
|
||||
image1 = [[TByteBitmapImageRep alloc] initFromFile:firstFilename];
|
||||
[image initFromFile: secondFilename ];//result will be in here
|
||||
//image is the composite of those two...
|
||||
[self composite:image1 to:image];
|
||||
}
|
||||
//
|
||||
// wolf stuff
|
||||
//
|
||||
newSize.width = 256;
|
||||
newSize.height = 256;
|
||||
|
||||
[image setSize: newSize];
|
||||
|
||||
if ([paramFileId output3DO] == YES) {
|
||||
image1 = [self scaleImage: image];
|
||||
[image dealloc];
|
||||
image = image1;
|
||||
}
|
||||
|
||||
numQuadCels = (([image pixelsWide] & 0xfff0)*([image pixelsHigh] & 0xfff0))/(MINSIZE*MINSIZE);
|
||||
numQuadCels += numQuadCels/4 + numQuadCels/16;
|
||||
|
||||
// if ([paramFileId deltaFrames] == YES && cleared == NO && [image isPlanar] == NO) {
|
||||
// cleared = YES;
|
||||
// imageData = [image data];
|
||||
// memset( imageData, 0, [image pixelsWide]*[image pixelsHigh]*[image samplesPerPixel]);
|
||||
// }
|
||||
|
||||
if (!quietMode) printf("loadAndDisplayImage: %dx%d\n", [image pixelsWide], [image pixelsHigh]);
|
||||
|
||||
if (!quietMode) {
|
||||
if (!cWindow) {
|
||||
cRect.origin.x = 8.0 * 48.0;
|
||||
cRect.origin.y = ([image pixelsHigh]+80);
|
||||
cRect.size.width = [image pixelsWide];
|
||||
cRect.size.height = [image pixelsHigh];
|
||||
cWindow = [[NSWindow alloc] initWithContentRect:cRect styleMask:NSTitledWindowMask
|
||||
backing:NSBackingStoreBuffered defer:NO];
|
||||
cRect.origin.x = cRect.origin.y = 0.0;
|
||||
// [[cWindow contentView] setClipping:NO];
|
||||
[cWindow setTitle: @"current frame"];
|
||||
[cWindow makeKeyAndOrderFront: [cWindow contentView]];
|
||||
[cWindow display];
|
||||
}
|
||||
|
||||
|
||||
cRect = [[cWindow contentView] bounds];
|
||||
[[cWindow contentView] lockFocus];
|
||||
[image drawInRect: cRect];
|
||||
[[cWindow contentView] unlockFocus];
|
||||
[cWindow flushWindow];
|
||||
|
||||
if (!eWindow) {
|
||||
cRect.origin.x = 8.0 * 48.0 - ([image pixelsWide]>>1) - 4;
|
||||
cRect.origin.y = ([image pixelsHigh]+80);
|
||||
cRect.size.width = [image pixelsWide] >> 1;
|
||||
cRect.size.height = [image pixelsHigh] >> 1;
|
||||
eWindow = [[NSWindow alloc] initWithContentRect:cRect styleMask:NSTitledWindowMask
|
||||
backing:NSBackingStoreBuffered defer:NO];
|
||||
cRect.origin.x = cRect.origin.y = 0.0;
|
||||
// [[eWindow contentView] setClipping:NO];
|
||||
[eWindow setTitle: @"cel error"];
|
||||
[eWindow makeKeyAndOrderFront: [eWindow contentView]];
|
||||
[eWindow display];
|
||||
}
|
||||
|
||||
if (!sWindow) {
|
||||
cRect.origin.x = 8.0 * 48.0 - ([image pixelsWide]>>1) - 4;
|
||||
cRect.origin.y = ([image pixelsHigh]+80) + (([image pixelsHigh]+48)>>1);
|
||||
cRect.size.width = [image pixelsWide] >> 1;
|
||||
cRect.size.height = [image pixelsHigh] >> 1;
|
||||
sWindow = [[NSWindow alloc] initWithContentRect: cRect styleMask:NSTitledWindowMask
|
||||
backing:NSBackingStoreBuffered defer:NO];
|
||||
cRect.origin.x = cRect.origin.y = 0.0;
|
||||
// [[eWindow contentView] setClipping:NO];
|
||||
[sWindow setTitle: @"quadtree map"];
|
||||
[sWindow makeKeyAndOrderFront: [sWindow contentView]];
|
||||
[sWindow display];
|
||||
}
|
||||
|
||||
cRect = [[sWindow contentView] bounds];
|
||||
[[sWindow contentView] lockFocus];
|
||||
[image drawInRect: cRect];
|
||||
[[sWindow contentView] unlockFocus];
|
||||
[sWindow flushWindow];
|
||||
|
||||
cRect = [[eWindow contentView] bounds];
|
||||
[[eWindow contentView] lockFocus];
|
||||
[image drawInRect: cRect];
|
||||
[[eWindow contentView] unlockFocus];
|
||||
[eWindow flushWindow];
|
||||
|
||||
if (!errImage) {
|
||||
errImage = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
|
||||
pixelsWide: 1
|
||||
pixelsHigh: 1
|
||||
bitsPerSample: 8
|
||||
samplesPerPixel: 3
|
||||
hasAlpha: NO
|
||||
isPlanar: NO
|
||||
colorSpaceName: NSCalibratedRGBColorSpace
|
||||
bytesPerRow: 0
|
||||
bitsPerPixel: 0];
|
||||
}
|
||||
|
||||
// NSPing();
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- markQuadx: (int)xat quady: (int)yat quads: (int)size error: (float)cerror type: (int)choice
|
||||
{
|
||||
NSRect cRect;
|
||||
byte *err;
|
||||
static int ywasat = -1;
|
||||
if (!quietMode) {
|
||||
cRect.origin.x = (xat)>>1;
|
||||
cRect.origin.y = ([image pixelsHigh] - yat - size)>>1;
|
||||
cRect.size.width = cRect.size.height = (size)>>1;
|
||||
|
||||
if (size < 1) {
|
||||
[[sWindow contentView] lockFocus];
|
||||
if (size == 8 && choice == 1) {
|
||||
PSsetgray(NSWhite);
|
||||
} else if (size == 8 && choice == 3) {
|
||||
PSsetgray(NSLightGray);
|
||||
} else if (size == 4) {
|
||||
PSsetgray(NSDarkGray);
|
||||
} else if (size == 2) {
|
||||
PSsetgray(NSBlack);
|
||||
}
|
||||
NSFrameRectWithWidth(cRect,0.0);
|
||||
[[sWindow contentView] unlockFocus];
|
||||
if (!(ywasat & 31)) {
|
||||
[sWindow flushWindow];
|
||||
}
|
||||
}
|
||||
|
||||
err = [errImage bitmapData];
|
||||
err[0] = err[1] = err[2] = 0;
|
||||
if ( cerror > 31 ) cerror = 31;
|
||||
if (choice & 1) err[0] = (int)cerror*8;
|
||||
if (choice & 2) err[1] = (int)cerror*8;
|
||||
if (choice & 4) err[2] = (int)cerror*8;
|
||||
|
||||
[[eWindow contentView] lockFocus];
|
||||
[errImage drawInRect: cRect];
|
||||
[[eWindow contentView] unlockFocus];
|
||||
if (!(ywasat & 31)) {
|
||||
[eWindow flushWindow];
|
||||
}
|
||||
ywasat++;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSBitmapImageRep*)currentImage
|
||||
{
|
||||
return image;
|
||||
}
|
||||
|
||||
- (id)errorWindow
|
||||
{
|
||||
return eWindow;
|
||||
}
|
||||
|
||||
- (id)scaleWindow
|
||||
{
|
||||
return sWindow;
|
||||
}
|
||||
- (int)numberOfFrames {
|
||||
return numberOfFrames;
|
||||
}
|
||||
|
||||
- composite:(NSBitmapImageRep *)source to: (NSBitmapImageRep *)destination
|
||||
{
|
||||
unsigned short value;
|
||||
int x,y,bpp,inc,pixelsWide,pixelsHigh,yoff,pixel;
|
||||
byte *iPlane[5], *dPlane[5];
|
||||
|
||||
bpp = [source samplesPerPixel];
|
||||
pixelsWide = [source pixelsWide];
|
||||
pixelsHigh = [source pixelsHigh];
|
||||
|
||||
if ([source isPlanar]) {
|
||||
[source getBitmapDataPlanes: iPlane];
|
||||
[destination getBitmapDataPlanes: dPlane];
|
||||
for(y=0;y<pixelsHigh;y++) {
|
||||
yoff = y*pixelsWide;
|
||||
for(x=0;x<pixelsWide;x++) {
|
||||
if ([destination hasAlpha]) {
|
||||
value = dPlane[3][yoff+x];
|
||||
} else {
|
||||
value = 255;
|
||||
}
|
||||
if (value == 0) {
|
||||
dPlane[0][yoff+x] = iPlane[0][yoff+x];
|
||||
dPlane[1][yoff+x] = iPlane[1][yoff+x];
|
||||
dPlane[2][yoff+x] = iPlane[2][yoff+x];
|
||||
dPlane[3][yoff+x] = iPlane[3][yoff+x];
|
||||
} else if (value != 255) {
|
||||
pixel = ((iPlane[0][yoff+x]*(255-value))/255) + ((dPlane[0][yoff+x]*value)/255);
|
||||
dPlane[0][yoff+x] = pixel;
|
||||
pixel = ((iPlane[1][yoff+x]*(255-value))/255) + ((dPlane[1][yoff+x]*value)/255);
|
||||
dPlane[1][yoff+x] = pixel;
|
||||
pixel = ((iPlane[2][yoff+x]*(255-value))/255) + ((dPlane[2][yoff+x]*value)/255);
|
||||
dPlane[2][yoff+x] = pixel;
|
||||
if ([destination hasAlpha]) {
|
||||
if (iPlane[3][yoff+x]>dPlane[3][yoff+x]) dPlane[3][yoff+x] = iPlane[3][yoff+x];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
iPlane[0] = [source bitmapData];
|
||||
dPlane[0] = [destination bitmapData];
|
||||
for(y=0;y<pixelsHigh;y++) {
|
||||
yoff = y*pixelsWide*bpp;
|
||||
for(x=0;x<pixelsWide;x++) {
|
||||
inc = x*bpp;
|
||||
if ([destination hasAlpha]) {
|
||||
value = dPlane[0][yoff+inc+3];
|
||||
} else {
|
||||
value = 255;
|
||||
}
|
||||
if (value == 0) {
|
||||
dPlane[0][yoff+inc+0] = iPlane[0][yoff+inc+0];
|
||||
dPlane[0][yoff+inc+1] = iPlane[0][yoff+inc+1];
|
||||
dPlane[0][yoff+inc+2] = iPlane[0][yoff+inc+2];
|
||||
dPlane[0][yoff+inc+3] = iPlane[0][yoff+inc+3];
|
||||
} else if (value != 255) {
|
||||
pixel = ((iPlane[0][yoff+inc+0]*(255-value))/255) + ((dPlane[0][yoff+inc+0]*value)/255);
|
||||
dPlane[0][yoff+inc+0] = pixel;
|
||||
pixel = ((iPlane[0][yoff+inc+1]*(255-value))/255) + ((dPlane[0][yoff+inc+1]*value)/255);
|
||||
dPlane[0][yoff+inc+1] = pixel;
|
||||
pixel = ((iPlane[0][yoff+inc+2]*(255-value))/255) + ((dPlane[0][yoff+inc+2]*value)/255);
|
||||
dPlane[0][yoff+inc+2] = pixel;
|
||||
if ([destination hasAlpha]) {
|
||||
if (iPlane[0][yoff+inc+3]>dPlane[0][yoff+inc+3]) dPlane[0][yoff+inc+3] = iPlane[0][yoff+inc+3];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
|
||||
|
||||
}
|
||||
@end
|
||||
635
neo/tools/compilers/roqvq/roqParam.cpp
Normal file
635
neo/tools/compilers/roqvq/roqParam.cpp
Normal file
@@ -0,0 +1,635 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 GPL Source Code
|
||||
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
|
||||
|
||||
Doom 3 Source Code 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#include "../../../idlib/precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "roqParam.h"
|
||||
|
||||
//
|
||||
// read a parameter file in (true I bloddy well had to do this again) (and yet again to c++)
|
||||
//
|
||||
|
||||
int parseRange(const char *rangeStr,int field, int skipnum[], int startnum[], int endnum[],int numfiles[],bool padding[],int numpadding[] );
|
||||
int parseTimecodeRange(const char *rangeStr,int field, int skipnum[], int startnum[], int endnum[],int numfiles[],bool padding[],int numpadding[] );
|
||||
|
||||
void roqParam::InitFromFile( const char *fileName )
|
||||
{
|
||||
idParser *src;
|
||||
idToken token;
|
||||
int i, readarg;
|
||||
|
||||
|
||||
src = new idParser( fileName, LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES );
|
||||
if ( !src->IsLoaded() ) {
|
||||
delete src;
|
||||
common->Printf("Error: can't open param file %s\n", fileName);
|
||||
return;
|
||||
}
|
||||
|
||||
common->Printf("initFromFile: %s\n", fileName);
|
||||
|
||||
fullSearch = false;
|
||||
scaleDown = false;
|
||||
encodeVideo = false;
|
||||
addPath = false;
|
||||
screenShots = false;
|
||||
startPalette = false;
|
||||
endPalette = false;
|
||||
fixedPalette = false;
|
||||
keyColor = false;
|
||||
justDelta = false;
|
||||
useTimecodeForRange = false;
|
||||
onFrame = 0;
|
||||
numInputFiles = 0;
|
||||
currentPath[0] = '\0';
|
||||
make3DO = false;
|
||||
makeVectors = false;
|
||||
justDeltaFlag = false;
|
||||
noAlphaAtAll = false;
|
||||
twentyFourToThirty = false;
|
||||
hasSound = false;
|
||||
isScaleable = false;
|
||||
firstframesize = 56*1024;
|
||||
normalframesize = 20000;
|
||||
jpegDefault = 85;
|
||||
|
||||
realnum = 0;
|
||||
while( 1 ) {
|
||||
if ( !src->ReadToken( &token ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
readarg = 0;
|
||||
// input dir
|
||||
if (token.Icmp( "input_dir") == 0) {
|
||||
src->ReadToken( &token );
|
||||
addPath = true;
|
||||
currentPath = token;
|
||||
// common->Printf(" + input directory is %s\n", currentPath );
|
||||
readarg++;
|
||||
continue;
|
||||
}
|
||||
// input dir
|
||||
if (token.Icmp( "scale_down") == 0) {
|
||||
scaleDown = true;
|
||||
// common->Printf(" + scaling down input\n" );
|
||||
readarg++;
|
||||
continue;
|
||||
}
|
||||
// full search
|
||||
if (token.Icmp( "fullsearch") == 0) {
|
||||
normalframesize += normalframesize/2;
|
||||
fullSearch = true;
|
||||
readarg++;
|
||||
continue;
|
||||
}
|
||||
// scaleable
|
||||
if (token.Icmp( "scaleable") == 0) {
|
||||
isScaleable = true;
|
||||
readarg++;
|
||||
continue;
|
||||
}
|
||||
// input dir
|
||||
if (token.Icmp( "no_alpha") == 0) {
|
||||
noAlphaAtAll = true;
|
||||
// common->Printf(" + scaling down input\n" );
|
||||
readarg++;
|
||||
continue;
|
||||
}
|
||||
if (token.Icmp( "24_fps_in_30_fps_out") == 0) {
|
||||
twentyFourToThirty = true;
|
||||
readarg++;
|
||||
continue;
|
||||
}
|
||||
// video in
|
||||
if (token.Icmp( "video_in") == 0) {
|
||||
encodeVideo = true;
|
||||
// common->Printf(" + Using the video port as input\n");
|
||||
continue;
|
||||
}
|
||||
//timecode range
|
||||
if (token.Icmp( "timecode") == 0) {
|
||||
useTimecodeForRange = true;
|
||||
firstframesize = 12*1024;
|
||||
normalframesize = 4500;
|
||||
// common->Printf(" + Using timecode as range\n");
|
||||
continue;
|
||||
}
|
||||
// soundfile for making a .RnR
|
||||
if (token.Icmp( "sound") == 0) {
|
||||
src->ReadToken( &token );
|
||||
soundfile = token;
|
||||
hasSound = true;
|
||||
// common->Printf(" + Using timecode as range\n");
|
||||
continue;
|
||||
}
|
||||
// soundfile for making a .RnR
|
||||
if (token.Icmp( "has_sound") == 0) {
|
||||
hasSound = true;
|
||||
continue;
|
||||
}
|
||||
// outfile
|
||||
if (token.Icmp( "filename") == 0) {
|
||||
src->ReadToken( &token );
|
||||
outputFilename = token;
|
||||
i = strlen(outputFilename);
|
||||
// common->Printf(" + output file is %s\n", outputFilename );
|
||||
readarg++;
|
||||
continue;
|
||||
}
|
||||
// starting palette
|
||||
if (token.Icmp( "start_palette") == 0) {
|
||||
src->ReadToken( &token );
|
||||
sprintf(startPal, "/LocalLibrary/vdxPalettes/%s", token.c_str());
|
||||
// common->Error(" + starting palette is %s\n", startPal );
|
||||
startPalette = true;
|
||||
readarg++;
|
||||
continue;
|
||||
}
|
||||
// ending palette
|
||||
if (token.Icmp( "end_palette") == 0) {
|
||||
src->ReadToken( &token );
|
||||
sprintf(endPal, "/LocalLibrary/vdxPalettes/%s", token.c_str());
|
||||
// common->Printf(" + ending palette is %s\n", endPal );
|
||||
endPalette = true;
|
||||
readarg++;
|
||||
continue;
|
||||
}
|
||||
// fixed palette
|
||||
if (token.Icmp( "fixed_palette") == 0) {
|
||||
src->ReadToken( &token );
|
||||
sprintf(startPal, "/LocalLibrary/vdxPalettes/%s", token.c_str());
|
||||
// common->Printf(" + fixed palette is %s\n", startPal );
|
||||
fixedPalette = true;
|
||||
readarg++;
|
||||
continue;
|
||||
}
|
||||
// these are screen shots
|
||||
if (token.Icmp( "screenshot") == 0) {
|
||||
// common->Printf(" + shooting screen shots\n" );
|
||||
screenShots = true;
|
||||
readarg++;
|
||||
continue;
|
||||
}
|
||||
// key_color r g b
|
||||
if (token.Icmp( "key_color") == 0) {
|
||||
keyR = src->ParseInt();
|
||||
keyG = src->ParseInt();
|
||||
keyB = src->ParseInt();
|
||||
keyColor = true;
|
||||
// common->Printf(" + key color is %03d %03d %03d\n", keyR, keyG, keyB );
|
||||
readarg++;
|
||||
continue;
|
||||
}
|
||||
// only want deltas
|
||||
if (token.Icmp( "just_delta") == 0) {
|
||||
// common->Printf(" + outputting deltas in the night\n" );
|
||||
// justDelta = true;
|
||||
// justDeltaFlag = true;
|
||||
readarg++;
|
||||
continue;
|
||||
}
|
||||
// doing 3DO
|
||||
if (token.Icmp( "3DO") == 0) {
|
||||
make3DO = true;
|
||||
readarg++;
|
||||
continue;
|
||||
}
|
||||
// makes codebook vector tables
|
||||
if (token.Icmp( "codebook") == 0) {
|
||||
makeVectors = true;
|
||||
readarg++;
|
||||
continue;
|
||||
}
|
||||
// set first frame size
|
||||
if (token.Icmp( "firstframesize") == 0) {
|
||||
firstframesize = src->ParseInt();
|
||||
readarg++;
|
||||
continue;
|
||||
}
|
||||
// set normal frame size
|
||||
if (token.Icmp( "normalframesize") == 0) {
|
||||
normalframesize = src->ParseInt();
|
||||
readarg++;
|
||||
continue;
|
||||
}
|
||||
// set normal frame size
|
||||
if (token.Icmp( "stillframequality") == 0) {
|
||||
jpegDefault = src->ParseInt();
|
||||
readarg++;
|
||||
continue;
|
||||
}
|
||||
if (token.Icmp( "input") == 0) {
|
||||
int num_files = 255;
|
||||
|
||||
range = (int *)Mem_ClearedAlloc( num_files * sizeof(int) );
|
||||
padding = (bool *)Mem_ClearedAlloc( num_files * sizeof(bool) );
|
||||
padding2 = (bool *)Mem_ClearedAlloc( num_files * sizeof(bool) );
|
||||
skipnum = (int *)Mem_ClearedAlloc( num_files * sizeof(int) );
|
||||
skipnum2 = (int *)Mem_ClearedAlloc( num_files * sizeof(int) );
|
||||
startnum = (int *)Mem_ClearedAlloc( num_files * sizeof(int) );
|
||||
startnum2 = (int *)Mem_ClearedAlloc( num_files * sizeof(int) );
|
||||
endnum = (int *)Mem_ClearedAlloc( num_files * sizeof(int) );
|
||||
endnum2 = (int *)Mem_ClearedAlloc( num_files * sizeof(int) );
|
||||
numpadding = (int *)Mem_ClearedAlloc( num_files * sizeof(int) );
|
||||
numpadding2 = (int *)Mem_ClearedAlloc( num_files * sizeof(int) );
|
||||
numfiles = (int *)Mem_ClearedAlloc( num_files * sizeof(int) );
|
||||
idStr empty;
|
||||
file.AssureSize( num_files, empty );
|
||||
file.AssureSize( num_files, empty );
|
||||
|
||||
field = 0;
|
||||
realnum = 0;
|
||||
do {
|
||||
src->ReadToken(&token);
|
||||
if ( token.Icmp( "end_input") != 0 ) {
|
||||
idStr arg1, arg2, arg3;
|
||||
|
||||
file[field] = token;
|
||||
while (src->ReadTokenOnLine( &token ) && token.Icmp( "[" ) ) {
|
||||
file[field].Append( token );
|
||||
}
|
||||
|
||||
arg1 = token;
|
||||
while (src->ReadTokenOnLine( &token ) && token.Icmp( "[" ) ) {
|
||||
arg1 += token;
|
||||
}
|
||||
|
||||
arg2 = token;
|
||||
while (src->ReadTokenOnLine( &token ) && token.Icmp( "[" ) ) {
|
||||
arg2 += token;
|
||||
}
|
||||
|
||||
arg3 = token;
|
||||
while (src->ReadTokenOnLine( &token ) && token.Icmp( "[" ) ) {
|
||||
arg3 += token;
|
||||
}
|
||||
|
||||
if ( arg1[0] != '[' ) {
|
||||
// common->Printf(" + reading %s\n", file[field] );
|
||||
range[field] = 0;
|
||||
numfiles[field] = 1;
|
||||
realnum++;
|
||||
}
|
||||
else {
|
||||
if ( arg1[0] == '[' )
|
||||
{
|
||||
range[field] = 1;
|
||||
if (useTimecodeForRange) {
|
||||
realnum += parseTimecodeRange( arg1, field, skipnum, startnum, endnum, numfiles, padding, numpadding);
|
||||
// common->Printf(" + reading %s from %d to %d\n", file[field], startnum[field], endnum[field]);
|
||||
}
|
||||
else {
|
||||
realnum += parseRange( arg1, field, skipnum, startnum, endnum, numfiles, padding, numpadding);
|
||||
// common->Printf(" + reading %s from %d to %d\n", file[field], startnum[field], endnum[field]);
|
||||
}
|
||||
}
|
||||
else if (( arg1[0] != '[' ) && ( arg2[0] == '[') && ( arg3[0] =='[')) { //a double ranger...
|
||||
int files1,files2;
|
||||
|
||||
file2[field] = arg1;
|
||||
range[field] = 2;
|
||||
files1 = parseRange(arg2, field, skipnum, startnum, endnum, numfiles, padding, numpadding);
|
||||
// common->Printf(" + reading %s from %d to %d\n", file[field], startnum[field], endnum[field]);
|
||||
files2 = parseRange(arg3, field, skipnum2, startnum2, endnum2, numfiles, padding2, numpadding2);
|
||||
// common->Printf(" + reading %s from %d to %d\n", file2[field], startnum2[field], endnum2[field]);
|
||||
if (files1 != files2) {
|
||||
common->Error( "You had %d files for %s and %d for %s!", files1, arg1.c_str(), files2, arg2.c_str() );
|
||||
}
|
||||
else {
|
||||
realnum += files1;//not both, they are parallel
|
||||
}
|
||||
}
|
||||
else {
|
||||
common->Error("Error: invalid range on open (%s %s %s)\n", arg1.c_str(), arg2.c_str(), arg3.c_str() );
|
||||
}
|
||||
}
|
||||
field++;
|
||||
}
|
||||
} while (token.Icmp( "end_input"));
|
||||
}
|
||||
}
|
||||
|
||||
if (TwentyFourToThirty()) realnum = realnum+(realnum>>2);
|
||||
numInputFiles = realnum;
|
||||
common->Printf(" + reading a total of %d frames in %s\n", numInputFiles, currentPath.c_str() );
|
||||
delete src;
|
||||
}
|
||||
|
||||
void roqParam::GetNthInputFileName( idStr &fileName, int n ) {
|
||||
int i, myfield, index,hrs,mins,secs,frs;
|
||||
char tempfile[33], left[256], right[256], *strp;
|
||||
if ( n > realnum ) n = realnum;
|
||||
// overcome starting at zero by ++ing and then --ing.
|
||||
if (TwentyFourToThirty()) { n++; n = (n/5) * 4 + (n % 5); n--; }
|
||||
|
||||
i = 0;
|
||||
myfield = 0;
|
||||
|
||||
while (i <= n) {
|
||||
i += numfiles[myfield++];
|
||||
}
|
||||
myfield--;
|
||||
i -= numfiles[myfield];
|
||||
|
||||
if ( range[myfield] == 1 ) {
|
||||
|
||||
strcpy( left, file[myfield] );
|
||||
strp = strstr( left, "*" );
|
||||
*strp++ = 0;
|
||||
sprintf(right, "%s", strp);
|
||||
|
||||
if ( startnum[myfield] <= endnum[myfield] ) {
|
||||
index = startnum[myfield] + ((n-i)*skipnum[myfield]);
|
||||
} else {
|
||||
index = startnum[myfield] - ((n-i)*skipnum[myfield]);
|
||||
}
|
||||
|
||||
if ( padding[myfield] == true ) {
|
||||
if (useTimecodeForRange) {
|
||||
hrs = index/(30*60*60) ;
|
||||
mins = (index/(30*60)) %60;
|
||||
secs = (index/(30)) % 60;
|
||||
frs = index % 30;
|
||||
sprintf(fileName,"%s%.02d%.02d/%.02d%.02d%.02d%.02d%s",left,hrs,mins,hrs,mins,secs,frs,right);
|
||||
}
|
||||
else {
|
||||
sprintf(tempfile, "%032d", index );
|
||||
sprintf(fileName, "%s%s%s", left, &tempfile[ 32-numpadding[myfield] ], right );
|
||||
}
|
||||
} else {
|
||||
if (useTimecodeForRange) {
|
||||
hrs = index/(30*60*60) ;
|
||||
mins = (index/(30*60)) %60;
|
||||
secs = (index/(30)) % 60;
|
||||
frs = index % 30;
|
||||
sprintf(fileName,"%s%.02d%.02d/%.02d%.02d%.02d%.02d%s",left,hrs,mins,hrs,mins,secs,frs,right);
|
||||
}
|
||||
else {
|
||||
sprintf(fileName, "%s%d%s", left, index, right );
|
||||
}
|
||||
}
|
||||
} else if ( range[myfield] == 2 ) {
|
||||
|
||||
strcpy( left, file[myfield] );
|
||||
strp = strstr( left, "*" );
|
||||
*strp++ = 0;
|
||||
sprintf(right, "%s", strp);
|
||||
|
||||
if ( startnum[myfield] <= endnum[myfield] ) {
|
||||
index = startnum[myfield] + ((n-i)*skipnum[myfield]);
|
||||
} else {
|
||||
index = startnum[myfield] - ((n-i)*skipnum[myfield]);
|
||||
}
|
||||
|
||||
if ( padding[myfield] == true ) {
|
||||
sprintf(tempfile, "%032d", index );
|
||||
sprintf(fileName, "%s%s%s", left, &tempfile[ 32-numpadding[myfield] ], right );
|
||||
} else {
|
||||
sprintf(fileName, "%s%d%s", left, index, right );
|
||||
}
|
||||
|
||||
strcpy( left, file2[myfield] );
|
||||
strp = strstr( left, "*" );
|
||||
*strp++ = 0;
|
||||
sprintf(right, "%s", strp);
|
||||
|
||||
if ( startnum2[myfield] <= endnum2[myfield] ) {
|
||||
index = startnum2[myfield] + ((n-i)*skipnum2[myfield]);
|
||||
} else {
|
||||
index = startnum2[myfield] - ((n-i)*skipnum2[myfield]);
|
||||
}
|
||||
|
||||
if ( padding2[myfield] == true ) {
|
||||
sprintf(tempfile, "%032d", index );
|
||||
fileName += va( "\n%s%s%s", left, &tempfile[ 32-numpadding2[myfield] ], right );
|
||||
} else {
|
||||
fileName += va( "\n%s%d%s", left, index, right );
|
||||
}
|
||||
} else {
|
||||
fileName = file[myfield];
|
||||
}
|
||||
}
|
||||
|
||||
const char* roqParam::GetNextImageFilename( void ) {
|
||||
idStr tempBuffer;
|
||||
int i;
|
||||
int len;
|
||||
|
||||
GetNthInputFileName( tempBuffer, onFrame++);
|
||||
if ( justDeltaFlag == true ) {
|
||||
onFrame--;
|
||||
justDeltaFlag = false;
|
||||
}
|
||||
|
||||
if ( addPath == true ) {
|
||||
currentFile = currentPath + "/" + tempBuffer;
|
||||
} else {
|
||||
currentFile = tempBuffer;
|
||||
}
|
||||
len = currentFile.Length();
|
||||
for(i=0;i<len;i++) {
|
||||
if (currentFile[i] == '^') {
|
||||
currentFile[i] = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
return currentFile.c_str();
|
||||
}
|
||||
|
||||
const char* roqParam::RoqFilename( void ) {
|
||||
return outputFilename.c_str();
|
||||
}
|
||||
|
||||
const char* roqParam::SoundFilename( void ) {
|
||||
return soundfile.c_str();
|
||||
}
|
||||
|
||||
const char* roqParam::RoqTempFilename( void ) {
|
||||
int i, j, len;
|
||||
|
||||
j = 0;
|
||||
len = outputFilename.Length();
|
||||
for(i=0; i<len; i++ )
|
||||
if ( outputFilename[i] == '/' ) j = i;
|
||||
|
||||
sprintf(tempFilename, "/%s.temp", &outputFilename[j+1] );
|
||||
|
||||
return tempFilename.c_str();
|
||||
}
|
||||
|
||||
bool roqParam::Timecode( void ) {
|
||||
return useTimecodeForRange;
|
||||
}
|
||||
|
||||
bool roqParam::OutputVectors( void ) {
|
||||
return makeVectors;
|
||||
}
|
||||
|
||||
bool roqParam::HasSound( void ) {
|
||||
return hasSound;
|
||||
}
|
||||
|
||||
bool roqParam::DeltaFrames( void ) {
|
||||
return justDelta;
|
||||
}
|
||||
|
||||
bool roqParam::NoAlpha( void ) {
|
||||
return noAlphaAtAll;
|
||||
}
|
||||
|
||||
bool roqParam::SearchType( void ) {
|
||||
return fullSearch;
|
||||
}
|
||||
|
||||
bool roqParam::MoreFrames( void ) {
|
||||
if (onFrame < numInputFiles) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool roqParam::TwentyFourToThirty( void ) {
|
||||
return twentyFourToThirty;
|
||||
}
|
||||
|
||||
int roqParam::NumberOfFrames( void ) {
|
||||
return numInputFiles;
|
||||
}
|
||||
|
||||
int roqParam::FirstFrameSize( void ) {
|
||||
return firstframesize;
|
||||
}
|
||||
|
||||
int roqParam::NormalFrameSize( void ) {
|
||||
return normalframesize;
|
||||
}
|
||||
|
||||
bool roqParam::IsScaleable( void ) {
|
||||
return isScaleable;
|
||||
}
|
||||
|
||||
int roqParam::JpegQuality( void ) {
|
||||
return jpegDefault;
|
||||
}
|
||||
|
||||
int parseRange(const char *rangeStr,int field, int skipnum[], int startnum[], int endnum[],int numfiles[],bool padding[],int numpadding[] ) {
|
||||
char start[64], end[64], skip[64];
|
||||
char *stptr, *enptr, *skptr;
|
||||
int i,realnum;
|
||||
|
||||
i = 1;
|
||||
realnum = 0;
|
||||
stptr = start;
|
||||
enptr = end;
|
||||
skptr = skip;
|
||||
do {
|
||||
*stptr++ = rangeStr[i++];
|
||||
} while ( rangeStr[i] >= '0' && rangeStr[i] <= '9' );
|
||||
*stptr = '\0';
|
||||
if ( rangeStr[i++] != '-' ) {
|
||||
common->Error("Error: invalid range on middle \n");
|
||||
}
|
||||
do {
|
||||
*enptr++ = rangeStr[i++];
|
||||
} while ( rangeStr[i] >= '0' && rangeStr[i] <= '9' );
|
||||
*enptr = '\0';
|
||||
if ( rangeStr[i] != ']' ) {
|
||||
if ( rangeStr[i++] != '+' ) {
|
||||
common->Error("Error: invalid range on close\n");
|
||||
}
|
||||
do {
|
||||
*skptr++ = rangeStr[i++];
|
||||
} while ( rangeStr[i] >= '0' && rangeStr[i] <= '9' );
|
||||
*skptr = '\0';
|
||||
skipnum[field] = atoi( skip );
|
||||
} else {
|
||||
skipnum[field] = 1;
|
||||
}
|
||||
startnum[field] = atoi( start );
|
||||
endnum[field] = atoi( end );
|
||||
numfiles[field] = (abs( startnum[field] - endnum[field] ) / skipnum[field]) + 1;
|
||||
realnum += numfiles[field];
|
||||
if ( start[0] == '0' && start[1] != '\0' ) {
|
||||
padding[field] = true;
|
||||
numpadding[field] = strlen( start );
|
||||
} else {
|
||||
padding[field] = false;
|
||||
}
|
||||
return realnum;
|
||||
}
|
||||
|
||||
int parseTimecodeRange(const char *rangeStr,int field, int skipnum[], int startnum[], int endnum[],int numfiles[],bool padding[],int numpadding[] )
|
||||
{
|
||||
char start[64], end[64], skip[64];
|
||||
char *stptr, *enptr, *skptr;
|
||||
int i,realnum,hrs,mins,secs,frs;
|
||||
|
||||
i = 1;//skip the '['
|
||||
realnum = 0;
|
||||
stptr = start;
|
||||
enptr = end;
|
||||
skptr = skip;
|
||||
do {
|
||||
*stptr++ = rangeStr[i++];
|
||||
} while ( rangeStr[i] >= '0' && rangeStr[i] <= '9' );
|
||||
*stptr = '\0';
|
||||
if ( rangeStr[i++] != '-' ) {
|
||||
common->Error("Error: invalid range on middle \n");
|
||||
}
|
||||
do {
|
||||
*enptr++ = rangeStr[i++];
|
||||
} while ( rangeStr[i] >= '0' && rangeStr[i] <= '9' );
|
||||
*enptr = '\0';
|
||||
if ( rangeStr[i] != ']' ) {
|
||||
if ( rangeStr[i++] != '+' ) {
|
||||
common->Error("Error: invalid range on close\n");
|
||||
}
|
||||
do {
|
||||
*skptr++ = rangeStr[i++];
|
||||
} while ( rangeStr[i] >= '0' && rangeStr[i] <= '9' );
|
||||
*skptr = '\0';
|
||||
skipnum[field] = atoi( skip );
|
||||
} else {
|
||||
skipnum[field] = 1;
|
||||
}
|
||||
sscanf(start,"%2d%2d%2d%2d",&hrs,&mins,&secs,&frs);
|
||||
startnum[field] = hrs*30*60*60 + mins *60*30 + secs*30 +frs;
|
||||
sscanf(end,"%2d%2d%2d%2d",&hrs,&mins,&secs,&frs);
|
||||
endnum[field] = hrs*30*60*60 + mins *60*30 + secs*30 +frs;
|
||||
numfiles[field] = (abs( startnum[field] - endnum[field] ) / skipnum[field]) + 1;
|
||||
realnum += numfiles[field];
|
||||
if ( start[0] == '0' && start[1] != '\0' ) {
|
||||
padding[field] = true;
|
||||
numpadding[field] = strlen( start );
|
||||
} else {
|
||||
padding[field] = false;
|
||||
}
|
||||
return realnum;
|
||||
}
|
||||
105
neo/tools/compilers/roqvq/roqParam.h
Normal file
105
neo/tools/compilers/roqvq/roqParam.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 GPL Source Code
|
||||
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
|
||||
|
||||
Doom 3 Source Code 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#ifndef __roqParam_h__
|
||||
#define __roqParam_h__
|
||||
|
||||
#include "gdefs.h"
|
||||
#pragma once
|
||||
|
||||
class roqParam
|
||||
{
|
||||
public:
|
||||
|
||||
const char* RoqFilename( void );
|
||||
const char* RoqTempFilename( void );
|
||||
const char* GetNextImageFilename( void );
|
||||
const char* SoundFilename( void );
|
||||
void InitFromFile( const char *fileName );
|
||||
void GetNthInputFileName( idStr &fileName, int n);
|
||||
bool MoreFrames( void );
|
||||
bool OutputVectors( void );
|
||||
bool Timecode( void );
|
||||
bool DeltaFrames( void );
|
||||
bool NoAlpha( void );
|
||||
bool SearchType( void );
|
||||
bool TwentyFourToThirty( void );
|
||||
bool HasSound( void );
|
||||
int NumberOfFrames( void );
|
||||
int NormalFrameSize( void );
|
||||
int FirstFrameSize( void );
|
||||
int JpegQuality( void );
|
||||
bool IsScaleable( void );
|
||||
|
||||
idStr outputFilename;
|
||||
int numInputFiles;
|
||||
private:
|
||||
int *range;
|
||||
bool *padding, *padding2;
|
||||
idStrList file;
|
||||
idStrList file2;
|
||||
idStr soundfile;
|
||||
idStr currentPath;
|
||||
idStr tempFilename;
|
||||
idStr startPal;
|
||||
idStr endPal;
|
||||
idStr currentFile;
|
||||
int *skipnum, *skipnum2;
|
||||
int *startnum, *startnum2;
|
||||
int *endnum, *endnum2;
|
||||
int *numpadding, *numpadding2;
|
||||
int *numfiles;
|
||||
byte keyR, keyG, keyB;
|
||||
int field;
|
||||
int realnum;
|
||||
int onFrame;
|
||||
int firstframesize;
|
||||
int normalframesize;
|
||||
int jpegDefault;
|
||||
|
||||
bool scaleDown;
|
||||
bool twentyFourToThirty;
|
||||
bool encodeVideo;
|
||||
bool useTimecodeForRange;
|
||||
bool addPath;
|
||||
bool screenShots;
|
||||
bool startPalette;
|
||||
bool endPalette;
|
||||
bool fixedPalette;
|
||||
bool keyColor;
|
||||
bool justDelta;
|
||||
bool make3DO;
|
||||
bool makeVectors;
|
||||
bool justDeltaFlag;
|
||||
bool noAlphaAtAll;
|
||||
bool fullSearch;
|
||||
bool hasSound;
|
||||
bool isScaleable;
|
||||
};
|
||||
|
||||
|
||||
#endif // roqParam
|
||||
Reference in New Issue
Block a user