doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
codec.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 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.
23 
24 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.
25 
26 ===========================================================================
27 */
28 #include "../../../idlib/precompiled.h"
29 #pragma hdrstop
30 
31 #include "codec.h"
32 
33 float glimit( const float val ) {
34  if (val<0) return 0;
35  if (val>255) return 255;
36  return val;
37 }
38 
40  int i;
41 
42  common->Printf("init: initing.....\n");
43  codebooksize = 256;
44  codebook2 = (VQDATA **) Mem_ClearedAlloc(256*sizeof(VQDATA *));
45  for(i=0; i < 256; i++) {
46  codebook2[i] = (VQDATA *) Mem_ClearedAlloc(16*sizeof(VQDATA));
47  }
48  codebook4 = (VQDATA **) Mem_ClearedAlloc(256*sizeof(VQDATA *));
49  for(i=0; i < 256; i++) {
50  codebook4[i] = (VQDATA *) Mem_ClearedAlloc(64*sizeof(VQDATA));
51  }
52  previousImage[0] = 0;
53  previousImage[1] = 0;
54  image = 0;
55  whichFrame = 0;
56  qStatus = 0;
57  luti = 0;
58  overAmount = 0;
59  codebookmade = 0;
60  slop = 0;
61 }
62 
64 {
65  common->Printf("codec: resetting\n");
66  if (qStatus) Mem_Free( qStatus);
67  if (luti) Mem_Free(luti);
68  if (previousImage[0]) delete previousImage[0];
69  if (previousImage[1]) delete previousImage[1];
70  qStatus = 0;
71  initRGBtab = 0;
72  previousImage[0] = 0;
73  whichFrame = 0;
74  luti = 0;
75  return;
76 }
77 
78 /* Because Shellsort is a variation on Insertion Sort, it has the same
79  * inconsistency that I noted in the InsertionSort class. Notice where I
80  * subtract a move to compensate for calling a swap for visual purposes.
81  */
82 
83 void codec::Sort( float *list, int *intIndex, int numElements )
84 {
85 #define STRIDE_FACTOR 3 // good value for stride factor is not well-understood
86  // 3 is a fairly good choice (Sedgewick)
87  int c,d, stride;
88  bool found;
89 
90  stride = 1;
91  while (stride <= numElements)
92  stride = stride*STRIDE_FACTOR +1;
93 
94  while (stride>(STRIDE_FACTOR-1)) { // loop to sort for each value of stride
95  stride = stride / STRIDE_FACTOR;
96 
97  for (c = stride; c < numElements; c++){
98  found = false;
99  d = c-stride;
100  while ((d >= 0) && !found) { // move to left until correct place
101  if (list[d]<list[d+stride]) {
102  float ftemp;
103  int itemp;
104  ftemp = list[d]; list[d] = list[d+stride]; list[d+stride] = ftemp;
105  itemp = intIndex[d]; intIndex[d] = intIndex[d+stride]; intIndex[d+stride] = itemp;
106  d -= stride; // jump by stride factor
107  } else
108  found = true;
109  }
110  }
111  }
112 }
113 
114 void codec::Segment( int *alist, float *flist, int numElements, float rmse)
115 {
116  int x, y, yy, xx, numc, onf, index, temp, best, a0, a1, a2, a3, bpp, i, len;
117  byte find[16], *lineout, *cbook, *src, *dst;
118  float fy, fcr, fcb;
119  idFile *fpcb;
120  char cbFile[256], tempcb[256], temptb[256];
121  bool doopen;
122  float y0,y1,y2,y3,cr,cb;
123 
124  doopen = false;
125  a0 = a1 = a2 = a3 = 0;
126 
127  sprintf( tempcb, "%s.cb", theRoQ->CurrentFilename());
128  sprintf( temptb, "%s.tb", theRoQ->CurrentFilename());
129 
130  onf = 0;
131  len = (int)strlen(tempcb);
132  for(x=0;x<len;x++) {
133  if (tempcb[x] == '\n') for(y=x;y<len;y++) if (tempcb[y] == '/') x = y+1;
134  cbFile[onf++] = tempcb[x];
135  }
136  cbFile[onf] = 0;
137 
138  lineout = (byte *)Mem_ClearedAlloc( 4*1024 );
139 
140  common->Printf("trying %s\n", cbFile);
141  fpcb = fileSystem->OpenFileRead( cbFile );
142  if ( !fpcb ) {
143  doopen = true;
144  common->Printf("failed....\n");
145  } else {
146  if ( dimension2 == 16 ) x = 3584; else x = 2560;
147  if ( fpcb->Read( lineout, x ) != x ) {
148  doopen = true;
149  common->Printf("failed....\n");
150  }
151  fileSystem->CloseFile( fpcb );
152  }
153 
154  if ( doopen ) {
155  common->Printf("segment: making %s\n", cbFile);
156  numc = numElements;
157  if (numElements > numc) numc = numElements;
158  onf = 0;
159 
160  for(x=0;x<256;x++) {
161  for(y=0;y<dimension2;y++) codebook2[x][y] = 0;
162  for(y=0;y<dimension4;y++) codebook4[x][y] = 0;
163  }
164 
165  bpp = image->samplesPerPixel();
166  cbook = (byte *)Mem_ClearedAlloc( 3 * image->pixelsWide() * image->pixelsHigh());
167  float *snrBook = (float *)Mem_ClearedAlloc( image->pixelsWide() * image->pixelsHigh() );
168  dst = cbook;
169  int numEntries = 0;
170  for (i=0; i<numQuadCels; i++) {
171  if (qStatus[i].size == 8 && qStatus[i].rsnr >= MIN_SNR*4) {
172  for(y=qStatus[i].yat;y<qStatus[i].yat+8; y+=4) {
173  for(x=qStatus[i].xat;x<qStatus[i].xat+8; x+=4) {
174  if (qStatus[i].rsnr == 9999.0f) {
175  snrBook[numEntries] = 1.0f;
176  } else {
177  snrBook[numEntries] = qStatus[i].rsnr;
178  }
179  numEntries++;
180  for(yy=y;yy<(y+4);yy++) {
181  for(xx=x;xx<(x+4);xx++) {
182  src = image->bitmapData() + (yy*(bpp*image->pixelsWide())) + (xx*bpp);
183  memcpy( dst, src, 3); dst += 3;
184  }
185  }
186  }
187  }
188  }
189  }
190  common->Printf("segment: %d 4x4 cels to vq\n", numEntries );
191 
192  VQ( numEntries, dimension4, cbook, snrBook, codebook4, true );
193 
194  dst = cbook;
195  numEntries = 0;
196 
197  for( i=0; i<256; i++ ) {
198  for(y=0;y<4;y+=2) {
199  for(x=0;x<4;x+=2) {
200  snrBook[numEntries] = 1.0f;
201  numEntries++;
202  for(yy=y;yy<(y+2);yy++) {
203  for(xx=x;xx<(x+2);xx++) {
204  dst[0] = codebook4[i][yy*12+xx*3+0];
205  dst[1] = codebook4[i][yy*12+xx*3+1];
206  dst[2] = codebook4[i][yy*12+xx*3+2];
207  dst += 3;
208  }
209  }
210  }
211  }
212  }
213  common->Printf("segment: %d 2x2 cels to vq\n", numEntries);
214 
215  VQ( numEntries, dimension2, cbook, snrBook, codebook2, false );
216 
217  Mem_Free(cbook);
218  Mem_Free(snrBook);
219 
220  index = 0;
221  for( onf = 0; onf < 256; onf++ ) {
222  numc = 0; fcr = fcb = 0;
223  for( x = 0; x < 4; x++ ) {
224  fy = RMULT*(float)(codebook2[onf][numc+0]) +
225  GMULT*(float)(codebook2[onf][numc+1]) +
226  BMULT*(float)(codebook2[onf][numc+2]) + 0.5f;
227  if (fy<0) fy = 0; if (fy>255) fy = 255;
228 
229  fcr += RIEMULT*(float)(codebook2[onf][numc+0]);
230  fcr += GIEMULT*(float)(codebook2[onf][numc+1]);
231  fcr += BIEMULT*(float)(codebook2[onf][numc+2]);
232 
233  fcb += RQEMULT*(float)(codebook2[onf][numc+0]);
234  fcb += GQEMULT*(float)(codebook2[onf][numc+1]);
235  fcb += BQEMULT*(float)(codebook2[onf][numc+2]);
236 
237  lineout[index++] = (byte)fy;
238  numc += 3;
239  }
240  fcr = (fcr/4)+128.5f; if (fcr<0) fcr = 0; if (fcr>255) fcr = 255;
241  fcb = (fcb/4)+128.5f; if (fcb<0) fcb = 0; if (fcb>255) fcr = 255;
242  //common->Printf(" fcr == %f, fcb == %f\n", fcr, fcb );
243  lineout[index++] = (byte)fcr;
244  lineout[index++] = (byte)fcb;
245  }
246 
247  for(onf=0;onf<256;onf++) {
248  for(y=0;y<4;y+=2) {
249  for(x=0;x<4;x+=2) {
250  numc = 0;
251  for(yy=y;yy<(y+2);yy++) {
252  temp = (yy*dimension2)+x*(dimension2/4);
253  find[numc++] = (byte)(codebook4[onf][temp+0] + 0.50f);
254  find[numc++] = (byte)(codebook4[onf][temp+1] + 0.50f);
255  find[numc++] = (byte)(codebook4[onf][temp+2] + 0.50f);
256  find[numc++] = (byte)(codebook4[onf][temp+3] + 0.50f);
257  find[numc++] = (byte)(codebook4[onf][temp+4] + 0.50f);
258  find[numc++] = (byte)(codebook4[onf][temp+5] + 0.50f);
259  }
260  lineout[index++] = BestCodeword( find, dimension2, codebook2 );
261  }
262  }
263  }
264 
265  fpcb = fileSystem->OpenFileWrite( cbFile );
266  common->Printf("made up %d entries\n", index);
267  fpcb->Write( lineout, index );
268  fileSystem->CloseFile( fpcb );
269  common->Printf("finished write\n");
270  }
271 
272  for(y=0;y<256;y++) {
273  x = y*6;
274  y0 = (float)lineout[x++];
275  y1 = (float)lineout[x++];
276  y2 = (float)lineout[x++];
277  y3 = (float)lineout[x++];
278  cb = (float)lineout[x++]; cb -= 128;
279  cr = (float)lineout[x ]; cr -= 128;
280  x = 0;
281  codebook2[y][x++] = glimit( y0 + 1.40200f*cr );
282  codebook2[y][x++] = glimit( y0 - 0.34414f*cb - 0.71414f*cr );
283  codebook2[y][x++] = glimit( y0 + 1.77200f*cb );
284  codebook2[y][x++] = glimit( y1 + 1.40200f*cr );
285  codebook2[y][x++] = glimit( y1 - 0.34414f*cb - 0.71414f*cr );
286  codebook2[y][x++] = glimit( y1 + 1.77200f*cb );
287  codebook2[y][x++] = glimit( y2 + 1.40200f*cr );
288  codebook2[y][x++] = glimit( y2 - 0.34414f*cb - 0.71414f*cr );
289  codebook2[y][x++] = glimit( y2 + 1.77200f*cb );
290  codebook2[y][x++] = glimit( y3 + 1.40200f*cr );
291  codebook2[y][x++] = glimit( y3 - 0.34414f*cb - 0.71414f*cr );
292  codebook2[y][x++] = glimit( y3 + 1.77200f*cb );
293  }
294 
295  index = 6*256;
296 
297  for(onf=0;onf<256;onf++) {
298  for(y=0;y<4;y+=2) {
299  for(x=0;x<4;x+=2) {
300  best = lineout[index++];
301  numc = 0;
302  for(yy=y;yy<(y+2);yy++) {
303  temp = (yy*dimension2)+x*(dimension2/4);
304  codebook4[onf][temp+0] = codebook2[best][numc++]; //r
305  codebook4[onf][temp+1] = codebook2[best][numc++]; //g
306  codebook4[onf][temp+2] = codebook2[best][numc++]; //b
307  codebook4[onf][temp+3] = codebook2[best][numc++]; //r a
308  codebook4[onf][temp+4] = codebook2[best][numc++]; //g r
309  codebook4[onf][temp+5] = codebook2[best][numc++]; //b g
310  }
311  }
312  }
313  }
314 
315  theRoQ->WriteCodeBook(lineout);
316  //PrepareCodeBook();
317 
318  Mem_Free(lineout);
319 }
320 
321 int codec::BestCodeword( unsigned char *tempvector, int dimension, VQDATA **codebook )
322 {
323  VQDATA dist;
324  VQDATA bestDist = HUGE;
325  VQDATA tempvq[64];
326  int bestIndex = -1;
327 
328  for( int i=0; i<dimension; i++ ) {
329  tempvq[i] = tempvector[i];
330  }
331 
332  for( int i=0; i<256; i++) {
333  dist = 0.0;
334  for( int x=0; x<dimension; x+=3 ) {
335  const VQDATA r0 = codebook[i][x];
336  const VQDATA r1 = tempvq[x];
337  const VQDATA g0 = codebook[i][x+1];
338  const VQDATA g1 = tempvq[x+1];
339  const VQDATA b0 = codebook[i][x+2];
340  const VQDATA b1 = tempvq[x+2];
341  dist += (r0-r1)*(r0-r1);
342  if (dist >= bestDist) {
343  continue;
344  }
345  dist += (g0-g1)*(g0-g1);
346  if (dist >= bestDist) {
347  continue;
348  }
349  dist += (b0-b1)*(b0-b1);
350  if (dist >= bestDist) {
351  continue;
352  }
353  }
354  if ( dist < bestDist ) {
355  bestDist = dist;
356  bestIndex = i;
357  }
358  }
359  return bestIndex;
360 }
361 
362 void codec::SetPreviousImage( const char*filename, NSBitmapImageRep *timage )
363 {
364  if (previousImage[0]) {
365  delete previousImage[0];
366  }
367  if (previousImage[1]) {
368  delete previousImage[1];
369  }
370  common->Printf("setPreviousImage:%s\n", filename);
371 
372  previousImage[0] = new NSBitmapImageRep( );
373  previousImage[1] = new NSBitmapImageRep( );
374  whichFrame=1;
375 
376  *previousImage[0] = *timage;
377  *previousImage[1] = *timage;
378 
381 
382  common->Printf("setPreviousImage: %dx%d\n", pixelsWide, pixelsHigh );
383 }
384 
386 {
387 int i, dy, dx, pluck, size, ind, xx, yy, pWide;
388 int x, y;
389 byte *rgbmap, *idataA, *fccdictionary;
390 bool diff;
391 
392  for(i=0;i<256;i++) { used2[i] = used4[i] = false; }
393 
394  pWide = pixelsWide & 0xfff0;
395  if (!previousImage[0]) {
396  previousImage[0] = new NSBitmapImageRep( pWide, (pixelsHigh & 0xfff0) );
397  previousImage[1] = new NSBitmapImageRep( pWide, (pixelsHigh & 0xfff0) );
398  }
399 
400  rgbmap = previousImage[(whichFrame&1)]->bitmapData();
401 
402  if ((whichFrame&1) == 1) {
403  fccdictionary = previousImage[0]->bitmapData();
404  } else {
405  fccdictionary = previousImage[1]->bitmapData();
406  }
407 
408  idataA = (byte *)Mem_Alloc( 16*16*4 );
409 
410  for(i=0;i<numQuadCels;i++) {
411  diff = false;
412  size = pquad[i].size;
413  if (size) {
414  switch( pquad[i].status ) {
415  case DEP:
416  break;
417  case SLD:
418  ind = pquad[i].patten[0];
419  used4[ind] = true;
420  for( dy=0; dy<size; dy++ ) {
421  pluck = (((dy+pquad[i].yat)*pWide)+pquad[i].xat)*4;
422  for( dx=0; dx<size; dx++ ) {
423  xx = ((dy>>1)*dimension2)+(dx>>1)*(dimension2/4);
424  if (rgbmap[pluck+0] != codebook4[ind][xx+0]) diff = true;
425  if (rgbmap[pluck+1] != codebook4[ind][xx+1]) diff = true;
426  if (rgbmap[pluck+2] != codebook4[ind][xx+2]) diff = true;
427  if (dimension4 == 64 && rgbmap[pluck+3] != codebook4[ind][xx+3]) diff = true;
428 
429  rgbmap[pluck+0] = (byte)codebook4[ind][xx+0];
430  rgbmap[pluck+1] = (byte)codebook4[ind][xx+1];
431  rgbmap[pluck+2] = (byte)codebook4[ind][xx+2];
432  if (dimension4 == 64)
433  rgbmap[pluck+3] = (byte)codebook4[ind][xx+3];
434  else
435  rgbmap[pluck+3] = 255;
436  pluck += 4;
437  }
438  }
439  if (diff == false && whichFrame) common->Printf("drawImage: SLD just changed the same thing\n");
440  break;
441  case PAT:
442  ind = pquad[i].patten[0];
443  used4[ind] = true;
444  for( dy=0; dy<size; dy++ ) {
445  pluck = (((dy+pquad[i].yat)*pWide)+pquad[i].xat)*4;
446  for( dx=0; dx<size; dx++ ) {
447  xx = (dy*size*(dimension2/4))+dx*(dimension2/4);
448  if (rgbmap[pluck+0] != codebook4[ind][xx+0]) diff = true;
449  if (rgbmap[pluck+1] != codebook4[ind][xx+1]) diff = true;
450  if (rgbmap[pluck+2] != codebook4[ind][xx+2]) diff = true;
451  if (dimension4 == 64 && rgbmap[pluck+3] != codebook4[ind][xx+3]) diff = true;
452 
453  rgbmap[pluck+0] = (byte)codebook4[ind][xx+0];
454  rgbmap[pluck+1] = (byte)codebook4[ind][xx+1];
455  rgbmap[pluck+2] = (byte)codebook4[ind][xx+2];
456  if (dimension4 == 64)
457  rgbmap[pluck+3] = (byte)codebook4[ind][xx+3];
458  else
459  rgbmap[pluck+3] = 255;
460  pluck += 4;
461  }
462  }
463  if (diff == false && whichFrame) common->Printf("drawImage: PAT just changed the same thing\n");
464  break;
465  case CCC:
466  dx = 1;
467  for(yy=0;yy<4;yy+=2) {
468  for(xx=0;xx<4;xx+=2) {
469  ind = pquad[i].patten[dx++];
470  used2[ind] = true;
471  dy = 0;
472  for(y=yy;y<(yy+2);y++) {
473  for(x=xx;x<(xx+2);x++) {
474  pluck = (((y+pquad[i].yat)*pWide)+(pquad[i].xat+x))*4;
475  if (rgbmap[pluck+0] != codebook2[ind][dy+0]) diff = true;
476  if (rgbmap[pluck+1] != codebook2[ind][dy+1]) diff = true;
477  if (rgbmap[pluck+2] != codebook2[ind][dy+2]) diff = true;
478  if (dimension4 == 64 && rgbmap[pluck+3] != codebook2[ind][dy+3]) diff = true;
479 
480  rgbmap[pluck+0] = (byte)codebook2[ind][dy+0];
481  rgbmap[pluck+1] = (byte)codebook2[ind][dy+1];
482  rgbmap[pluck+2] = (byte)codebook2[ind][dy+2];
483  if (dimension4 == 64) {
484  rgbmap[pluck+3] = (byte)codebook2[ind][dy+3];
485  dy += 4;
486  } else {
487  rgbmap[pluck+3] = 255;
488  dy += 3;
489  }
490  }
491  }
492  }
493  }
494  if (diff == false && whichFrame) {
495  /*
496  common->Printf("drawImage: CCC just changed the same thing\n");
497  common->Printf("sparseEncode: something is wrong here\n");
498  common->Printf("xat: %d\n", pquad[i].xat);
499  common->Printf("yat: %d\n", pquad[i].yat);
500  common->Printf("size %d\n", pquad[i].size);
501  common->Printf("type: %d\n", pquad[i].status);
502  common->Printf("motsnr: %0f\n", pquad[i].snr[FCC]);
503  common->Printf("cccsnr: %0f\n", pquad[i].snr[CCC]);
504  common->Printf("rmse: %0f\n", pquad[i].rsnr);
505  common->Printf("pat0: %0d\n", pquad[i].patten[1]);
506  common->Printf("pat1: %0d\n", pquad[i].patten[2]);
507  common->Printf("pat2: %0d\n", pquad[i].patten[3]);
508  common->Printf("pat3: %0d\n", pquad[i].patten[4]);
509  //exit(1);
510  */
511  }
512  break;
513  case FCC:
514  dx = pquad[i].xat - ((pquad[i].domain >> 8 ) - 128);
515  dy = pquad[i].yat - ((pquad[i].domain & 0xff) - 128);
516  if (image->pixelsWide()==(image->pixelsHigh()*4)) dx = pquad[i].xat - ((pquad[i].domain >> 8 ) - 128)*2;
517  if (theRoQ->Scaleable()) {
518  dx = pquad[i].xat - ((pquad[i].domain >> 8 ) - 128)*2;
519  dy = pquad[i].yat - ((pquad[i].domain & 0xff) - 128)*2;
520  }
521 // if (pquad[i].yat == 0) common->Printf("dx = %d, dy = %d, xat = %d\n", dx, dy, pquad[i].xat);
522 
523  ind = (dy*pWide+dx)*4;
524  for( dy=0; dy<size; dy++ ) {
525  pluck = (((dy+pquad[i].yat)*pWide)+pquad[i].xat)*4;
526  for( dx=0; dx<size; dx++ ) {
527  if (rgbmap[pluck+0] != fccdictionary[ind+0]) diff = true;
528  if (rgbmap[pluck+1] != fccdictionary[ind+1]) diff = true;
529  if (rgbmap[pluck+2] != fccdictionary[ind+2]) diff = true;
530 
531  rgbmap[pluck+0] = fccdictionary[ind+0];
532  rgbmap[pluck+1] = fccdictionary[ind+1];
533  rgbmap[pluck+2] = fccdictionary[ind+2];
534  rgbmap[pluck+3] = fccdictionary[ind+3];
535  pluck += 4; ind += 4;
536  }
537  ind += (pWide - size)*4;
538  }
539 // if (diff == false && whichFrame) common->Printf("drawImage: FCC just changed the same thing\n");
540  break;
541  case MOT:
542  break;
543  default:
544  common->Error( "bad code!!\n");
545  break;
546  }
547  }
548  }
549  if (whichFrame == 0) {
550  memcpy( previousImage[1]->bitmapData(), previousImage[0]->bitmapData(), pWide*(pixelsHigh & 0xfff0)*4);
551  }
552 
553  x = 0; y = 0;
554  for(i=0;i<256;i++) {
555  if (used4[i]) x++;
556  if (used2[i]) y++;
557  }
558 
559  if (theRoQ->IsQuiet() == false) common->Printf("drawImage: used %d 4x4 and %d 2x2 VQ cels\n", x,y);
560 
561  Mem_Free( idataA );
562 }
563 
564 void codec::InitImages( void )
565 {
566 int x,y, index0, index1, temp;
567 float ftemp;
568 byte *lutimage;
569 
570  numQuadCels = ((pixelsWide & 0xfff0)*(pixelsHigh & 0xfff0))/(MINSIZE*MINSIZE);
572 
573  if (qStatus) Mem_Free(qStatus);
575  InitQStatus();
576 //
577  if (previousImage[0]) {
580  temp = ((whichFrame+1)&1);
582  lutimage = previousImage[temp]->bitmapData();
583  if (theRoQ->IsQuiet() == false) {
584  common->Printf("initImage: remaking lut image using buffer %d\n", temp);
585  }
586  index0 = index1 = 0;
587  for(y=0;y<pixelsHigh; y++) {
588  for(x=0;x<pixelsWide; x++) {
589  ftemp = RMULT*lutimage[index0+0] + GMULT*lutimage[index0+1] + BMULT*lutimage[index0+2];
590  temp = (int)ftemp;
591  luti[index1] = temp;
592 
593  index0 += previousImage[0]->samplesPerPixel();
594  index1++;
595  }
596  }
597  }
598 }
599 
600 
601 void codec::QuadX( int startX, int startY, int quadSize)
602 {
603 int startSize;
604 int bigx, bigy, lowx, lowy;
605 
606  lowx = lowy = 0;
607  bigx = pixelsWide & 0xfff0;
608  bigy = pixelsHigh & 0xfff0;
609 
610  if ( (startX >= lowx) && (startX+quadSize) <= (bigx) && (startY+quadSize) <= (bigy) && (startY >= lowy) && quadSize <= MAXSIZE) {
611  qStatus[onQuad].size = quadSize;
612  qStatus[onQuad].xat = startX;
613  qStatus[onQuad].yat = startY;
614  qStatus[onQuad].rsnr = 999999;
615  onQuad++;
616  }
617 
618  if (quadSize != MINSIZE) {
619  startSize = quadSize>>1;
620  QuadX( startX , startY , startSize );
621  QuadX( startX+startSize , startY , startSize );
622  QuadX( startX , startY+startSize , startSize );
623  QuadX( startX+startSize , startY+startSize , startSize );
624  }
625 }
626 
627 void codec::InitQStatus( void )
628 {
629 int i,x,y;
630 
631  for (i=0; i<numQuadCels; i++)
632  qStatus[i].size = 0;
633 
634  onQuad = 0;
635  for(y=0;y<pixelsHigh; y+=16) {
636  for(x=0;x<pixelsWide; x+=16) {
637  QuadX( x, y,16 );
638  }
639  }
640 }
641 
642 
643 void codec::VqData8( byte *cel, quadcel *pquad )
644 {
645 byte tempImage[8*8*4];
646 int x, y, i, best, temp;
647 
648  i = 0;
649  for(y=0;y<4;y++) {
650  for(x=0;x<4;x++) {
651  temp = y*64+x*8;
652  tempImage[i++] = (cel[temp+0]+cel[temp+4]+cel[temp+32]+cel[temp+36])/4;
653  tempImage[i++] = (cel[temp+1]+cel[temp+5]+cel[temp+33]+cel[temp+37])/4;
654  tempImage[i++] = (cel[temp+2]+cel[temp+6]+cel[temp+34]+cel[temp+38])/4;
655  if (dimension4 == 64)
656  tempImage[i++] = (cel[temp+3]+cel[temp+7]+cel[temp+35]+cel[temp+39])/4;
657  }
658  }
659 
660  pquad->patten[0] = best = BestCodeword( tempImage, dimension4, codebook4 );
661 
662  for(y=0;y<8;y++) {
663  for(x=0;x<8;x++) {
664  temp = y*32+x*4;
665  i = ((y/2)*4*(dimension2/4))+(x/2)*(dimension2/4);
666  tempImage[temp+0] = (byte)codebook4[best][i+0];
667  tempImage[temp+1] = (byte)codebook4[best][i+1];
668  tempImage[temp+2] = (byte)codebook4[best][i+2];
669  if (dimension4 == 64)
670  tempImage[temp+3] = (byte)codebook4[best][i+3];
671  else
672  tempImage[temp+3] = 255;
673  }
674  }
675 
676  pquad->snr[SLD] = Snr( cel, tempImage, 8 )+1.0;
677 }
678 
679 void codec::VqData4( byte *cel, quadcel *pquad )
680 {
681 byte tempImage[64];
682 int i, best, bpp;
683 
684 // if (theRoQ->makingVideo] && previousImage[0]) return self;
685  if (dimension4 == 64) bpp = 4; else bpp = 3;
686  for(i=0;i<16;i++) {
687  tempImage[i*bpp+0] = cel[i*4+0];
688  tempImage[i*bpp+1] = cel[i*4+1];
689  tempImage[i*bpp+2] = cel[i*4+2];
690  if (dimension4 == 64) tempImage[i*bpp+3] = cel[i*4+3];
691  }
692 
693  pquad->patten[0] = best = BestCodeword( tempImage, dimension4, codebook4 );
694 
695  for(i=0;i<16;i++) {
696  tempImage[i*4+0] = (byte)codebook4[best][i*bpp+0];
697  tempImage[i*4+1] = (byte)codebook4[best][i*bpp+1];
698  tempImage[i*4+2] = (byte)codebook4[best][i*bpp+2];
699  if (dimension4 == 64)
700  tempImage[i*4+3] = (byte)codebook4[best][i*bpp+3];
701  else
702  tempImage[i*4+3] = 255;
703  }
704 
705  pquad->snr[PAT] = Snr( cel, tempImage, 4 );
706 }
707 
708 void codec::VqData2( byte *cel, quadcel *pquad )
709 {
710 byte tempImage[16], tempOut[64];
711 int i, j, best,x,y,xx,yy,bpp;
712 
713  if (dimension4 == 64) bpp = 4; else bpp = 3;
714  j = 1;
715  for(yy=0;yy<4;yy+=2) {
716  for(xx=0;xx<4;xx+=2) {
717  i = 0;
718  for(y=yy;y<(yy+2);y++) {
719  for(x=xx;x<(xx+2);x++) {
720  tempImage[i++] = cel[y*16+x*4+0];
721  tempImage[i++] = cel[y*16+x*4+1];
722  tempImage[i++] = cel[y*16+x*4+2];
723  if (dimension4 == 64) tempImage[i++] = cel[y*16+x*4+3];
724  }
725  }
726  pquad->patten[j++] = best = BestCodeword( tempImage, dimension2, codebook2 );
727  i = 0;
728  for(y=yy;y<(yy+2);y++) {
729  for(x=xx;x<(xx+2);x++) {
730  tempOut[y*16+x*4+0] = (byte)codebook2[best][i++];
731  tempOut[y*16+x*4+1] = (byte)codebook2[best][i++];
732  tempOut[y*16+x*4+2] = (byte)codebook2[best][i++];
733  if (dimension4 == 64)
734  tempOut[y*16+x*4+3] = (byte)codebook2[best][i++];
735  else
736  tempOut[y*16+x*4+3] = 255;
737  }
738  }
739  }
740  }
741 
742  pquad->snr[CCC] = Snr( cel, tempOut, 4 );
743 }
744 
745 void codec::IRGBtab(void)
746 {
747  initRGBtab++;
748 }
749 
750 float codec::Snr( byte *old, byte *bnew, int size ) {
751 int i, j;
752 float fsnr;
753 register int ind;
754 
755  ind = 0;
756 
757  for(i=0; i<size; i++) {
758  for(j=0; j<size; j++) {
759  if (old[3]||bnew[3]) ind += RGBADIST( old, bnew );
760  old += 4; bnew += 4;
761  }
762  }
763 
764  fsnr = (float)ind;
765  fsnr /= (size*size);
766  fsnr = (float)sqrt( fsnr );
767 
768  return (fsnr);
769 }
770 
771 int codec::ComputeMotionBlock( byte *old, byte *bnew, int size )
772 {
773 int i,j,snr;
774 
775  if (dimension4==64) return 0; // do not use this for alpha pieces
776  snr = 0;
777 
778  for(i=0; i<size; i++) {
779  for(j=0; j<size; j++) {
780  snr += RGBADIST( old, bnew );
781  old += 4; bnew += 4;
782  }
783  }
784  snr /= (size*size);
785  return ( snr <= MOTION_MIN );
786 }
787 
788 void codec::FvqData( byte *bitmap, int size, int realx, int realy, quadcel *pquad, bool clamp)
789 {
790  int x, y, xLen, yLen, mblur0, ripl, bpp, fabort, temp1;
791  int lowX, lowY, onx, ony, sX, sY, depthx, depthy, breakHigh;
792  float lowestSNR, fmblur0;
793  byte *scale1;
794  byte *bitma2;
795  int searchY, searchX, xxMean, yyMean;
796 
797  if ( !previousImage[0] || dimension4 == 64) {
798  return;
799  }
800 
801  for(x=0; x<(size*size); x++) {
802  fmblur0 = RMULT*bitmap[x*4+0] + GMULT*bitmap[x*4+1] + BMULT*bitmap[x*4+2];
803  luty[x] = (byte)fmblur0;
804  }
805  if (!luti) {
806  pquad->domain = 0x8080;
807  pquad->snr[FCC] = 9999;
808  return;
809  }
810 
811  ony = realy - (realy & 0xfff0);
812  onx = realx - (realx & 0xfff0);
813 
814  xLen = previousImage[0]->pixelsWide();
815  yLen = previousImage[0]->pixelsHigh();
816  ripl = xLen-size;
817 
818  breakHigh = 99999999;
819 
820  fabort = 0;
821  lowX = lowY = -1;
822  depthx = depthy = 1;
823  searchY = 8; //16;
824  searchX = 8; //32;
825  //if (xLen == (yLen*4)) depthx = 2;
826  //if (theRoQ->Scaleable()) depthx = depthy = 2;
827 
828  if (clamp) { searchX = searchY = 8; }
829  searchX = searchX*depthx;
830  searchY = searchY*depthy;
831  xxMean = dxMean*depthx;
832  yyMean = dyMean*depthy;
833 
834  if (((realx-xxMean)+searchX)<0 ||(((realx-xxMean)-searchX)+depthx+size)>xLen || ((realy-yyMean)+searchY)<0 || (((realy-yyMean)-searchY)+depthy+size)>yLen) {
835  pquad->snr[FCC] = 9999;
836  return;
837  }
838 
839  int sPsQ = -1;
840  for( sX=(((realx-xxMean)-searchX)+depthx); sX<=((realx-xxMean)+searchX) && !fabort; sX+=depthx ) {
841  for( sY=(((realy-yyMean)-searchY)+depthy); sY<=((realy-yyMean)+searchY) && breakHigh; sY+=depthy ) {
842  temp1 = xLen*sY+sX;
843  if ( sX >= 0 && (sX+size) <= xLen && sY >= 0 && (sY+size) <= yLen ) {
844  bpp = previousImage[0]->samplesPerPixel();
845  ripl = (xLen-size)*bpp;
846  mblur0 = 0;
847  bitma2 = bitmap;
848  scale1 = previousImage[((whichFrame+1)&1)]->bitmapData() + temp1*bpp;
849 // mblur0 = 0;
850 // bitma2 = luty;
851 // scale1 = luti + temp1;
852  for( y=0; y<size; y++) {
853  for( x=0; x<size; x++) {
854  mblur0 += RGBADIST( bitma2, scale1);
855  bitma2 += 4; scale1 += 4;
856  }
857  if (mblur0 > breakHigh) {
858  break;
859  }
860  scale1 += ripl;
861  }
862  if (breakHigh > mblur0) {
863  breakHigh = mblur0;
864  lowX = sX;
865  lowY = sY;
866  }
867  }
868  }
869  }
870 
871  if (lowX != -1 && lowY != -1) {
872  bpp = previousImage[0]->samplesPerPixel();
873  ripl = (xLen-size)*bpp;
874  mblur0 = 0;
875  bitma2 = bitmap;
876  scale1 = previousImage[((whichFrame+1)&1)]->bitmapData() + (xLen*lowY+lowX)*bpp;
877  for( y=0; y<size; y++) {
878  for( x=0; x<size; x++) {
879  mblur0 += RGBADIST( bitma2, scale1 );
880  scale1 += 4; bitma2 += 4;
881  }
882  scale1 += ripl;
883  }
884 
885 
886  lowestSNR = (float)mblur0;
887  lowestSNR /= (size*size);
888  lowestSNR = (float)sqrt( lowestSNR );
889 
890  sX = (realx-lowX+128);
891  sY = (realy-lowY+128);
892 
893  if (depthx==2) {
894  sX = ((realx-lowX)/2+128);
895  }
896  if (depthy==2) {
897  sY = ((realy-lowY)/2+128);
898  }
899  pquad->domain = (sX<<8)+sY;
900  pquad->snr[FCC] = lowestSNR;
901  }
902 }
903 
904 
905 void codec::GetData( unsigned char *iData, int qSize, int startX, int startY, NSBitmapImageRep *bitmap)
906 {
907 int x,y,yoff,bpp,yend,xend;
908 byte *iPlane[5];
909 int r,g,b,a;
910 
911  yend = qSize+startY;
912  xend = qSize+startX;
913 
914  if (startY > bitmap->pixelsHigh()) return;
915 
916  if (yend > bitmap->pixelsHigh()) yend = bitmap->pixelsHigh();
917  if (xend > bitmap->pixelsWide()) xend = bitmap->pixelsWide();
918 
919  bpp = bitmap->samplesPerPixel();
920 
921  if (bitmap->hasAlpha()) {
922  iPlane[0] = bitmap->bitmapData();
923  for(y=startY;y<yend;y++) {
924  yoff = y*bitmap->pixelsWide()*bpp;
925  for(x=startX;x<xend;x++) {
926  r = iPlane[0][yoff+(x*bpp)+0];
927  g = iPlane[0][yoff+(x*bpp)+1];
928  b = iPlane[0][yoff+(x*bpp)+2];
929  a = iPlane[0][yoff+(x*bpp)+3];
930  *iData++ = r; *iData++ = g; *iData++ = b; *iData++ = a;
931  }
932  }
933  } else {
934  iPlane[0] = bitmap->bitmapData();
935  for(y=startY;y<yend;y++) {
936  yoff = y*bitmap->pixelsWide()*bpp;
937  for(x=startX;x<xend;x++) {
938  r = iPlane[0][yoff+(x*bpp)+0];
939  g = iPlane[0][yoff+(x*bpp)+1];
940  b = iPlane[0][yoff+(x*bpp)+2];
941  *iData++ = r; *iData++ = g; *iData++ = b;
942  *iData++ = 255;
943  }
944  }
945  }
946 }
947 
948 void codec::LowestQuad( quadcel*qtemp, int* status, float* snr, int bweigh)
949 {
950 float wtemp;
951 float quickadd[DEAD];
952 int i;
953 
954  quickadd[CCC] = 1;
955  quickadd[SLD] = 1;
956  quickadd[MOT] = 1;
957  quickadd[FCC] = 1;
958  quickadd[PAT] = 1;
959 /*
960  if (slop > theRoQ->NormalFrameSize()) {
961  quickadd[CCC] = 0.5f;
962  quickadd[PAT] = 1.0f;
963  }
964 */
965  wtemp = 99999;
966 
967  for(i=(DEAD-1);i>0;i--) {
968  if ( qtemp->snr[i]*quickadd[i] < wtemp ) {
969  *status = i;
970  *snr = qtemp->snr[i];
971  wtemp = qtemp->snr[i]*quickadd[i];
972  }
973  }
974 
975  if ( qtemp->mark ) *status = MOT;
976 }
977 
979 {
980 int totalbits, i, totalbytes;
981 int quickadd[DEAD+1];
982 
983  totalbits = 0;
984 
985  quickadd[DEP] = 2;
986  quickadd[SLD] = 10;
987  quickadd[PAT] = 10;
988  quickadd[CCC] = 34;
989  quickadd[MOT] = 2;
990  quickadd[FCC] = 10;
991  quickadd[DEAD] = 0;
992 
993  for( i=0; i<numQuadCels; i++ ) {
994  if (pquad[i].size && pquad[i].size < 16 ) totalbits += quickadd[pquad[i].status];
995  }
996 
997  totalbytes = (totalbits >> 3)+2;
998  return (totalbytes);
999 }
1000 
1002 {
1003 int i, j;
1004 double totalbits;
1005 
1006  totalbits = 0;
1007  j = 0;
1008  for( i=0; i<numQuadCels; i++ ) {
1009  if (pquad[i].size && pquad[i].status && pquad[i].status != DEAD) {
1010  if (pquad[i].size == 8) { totalbits += pquad[i].rsnr*4; j += 4; }
1011  if (pquad[i].size == 4) { totalbits += pquad[i].rsnr*1; j += 1; }
1012  }
1013  }
1014  totalbits /= j;
1015  return ((float)totalbits);
1016 }
1017 
1018 int codec::AddQuad( quadcel *pquad, int lownum )
1019 {
1020 int i, nx, nsize;
1021 float newsnr, cmul;
1022 byte *idataA, *idataB;
1023 
1024  if (lownum != -1) {
1025 
1026  if (pquad[lownum].size == 8) {
1027  nx = 1; nsize = 4; cmul = 1;
1028  } else {
1029  nx = 5; nsize = 8; cmul = 4;
1030  }
1031  newsnr = 0;
1032  idataA = (byte *)Mem_Alloc(8*8*4);
1033  idataB = (byte *)Mem_Alloc(8*8*4);
1034  for( i=lownum+1; i<lownum+(nx*4)+1; i+=nx ) {
1035  pquad[i].size = nsize;
1036  GetData( idataA, pquad[i].size, pquad[i].xat, pquad[i].yat, image );
1037  VqData4( idataA ,&pquad[i] );
1038  VqData2( idataA, &pquad[i] );
1039  if (previousImage[0]) {
1040  FvqData( idataA, pquad[i].size, pquad[i].xat, pquad[i].yat, &pquad[i], true );
1041  GetData( idataB, pquad[i].size, pquad[i].xat, pquad[i].yat, previousImage[whichFrame&1] );
1042  pquad[i].snr[MOT] = Snr( idataA, idataB, pquad[i].size );
1043  if (ComputeMotionBlock( idataA, idataB, pquad[i].size ) && !theRoQ->IsLastFrame() && !detail) {
1044  pquad[i].mark = true;
1045  }
1046  }
1047  LowestQuad( &pquad[i] ,&pquad[i].status, &pquad[i].rsnr, true );
1048  newsnr += pquad[i].rsnr;
1049  }
1050  Mem_Free(idataA); Mem_Free(idataB);
1051  newsnr /= 4;
1052  LowestQuad( &pquad[lownum], &pquad[lownum].status, &pquad[lownum].rsnr, false );
1053 
1054  if ( pquad[lownum+nx*0+1].status == MOT && pquad[lownum+nx*1+1].status == MOT
1055  && pquad[lownum+nx*2+1].status == MOT && pquad[lownum+nx*3+1].status == MOT
1056  && nsize == 4) { newsnr = 9999; pquad[lownum].status = MOT; }
1057 
1058  if ( pquad[lownum].rsnr > newsnr ) {
1059  pquad[lownum].status = DEP;
1060  pquad[lownum].rsnr = 0;
1061  for( i=lownum+1; i<lownum+(nx*4)+1; i+=nx ) {
1062  theRoQ->MarkQuadx( pquad[i].xat, pquad[i].yat, nsize, pquad[i].rsnr, qStatus[i].status );
1063  }
1064  } else {
1065  theRoQ->MarkQuadx( pquad[lownum].xat, pquad[lownum].yat, nsize*2, pquad[lownum].rsnr, qStatus[lownum].status );
1066  pquad[lownum+nx*0+1].status = 0;
1067  pquad[lownum+nx*1+1].status = 0;
1068  pquad[lownum+nx*2+1].status = 0;
1069  pquad[lownum+nx*3+1].status = 0;
1070  pquad[lownum+nx*0+1].size = 0;
1071  pquad[lownum+nx*1+1].size = 0;
1072  pquad[lownum+nx*2+1].size = 0;
1073  pquad[lownum+nx*3+1].size = 0;
1074  }
1075  } else {
1076  lownum = -1;
1077  }
1078  return lownum;
1079 }
1080 
1081 int codec::MotMeanX( void )
1082 {
1083  return dxMean;
1084 }
1085 
1086 int codec::MotMeanY( void )
1087 {
1088  return dyMean;
1089 }
1090 
1092 {
1093 int i, j, osize, fsize, num[DEAD+1], *ilist, onf, ong, wtype, temp;
1094 float *flist, sRMSE, numredo;
1095 byte *idataA, *idataB;
1096 
1097  osize = 8;
1098 
1099  image = theRoQ->CurrentImage();
1100  newImage = 0;
1101 
1102  pixelsHigh = image->pixelsHigh();
1103  pixelsWide = image->pixelsWide();
1104 
1105  dimension2 = 12; dimension4 = 48;
1106  if (image->hasAlpha()&&(theRoQ->ParamNoAlpha() == false)) { dimension2 = 16; dimension4 = 64; }
1107 
1108  idataA = (byte *)Mem_Alloc( 16*16*4 );
1109  idataB = (byte *)Mem_Alloc( 16*16*4 );
1110 
1111  if (!previousImage[0]) common->Printf("sparseEncode: sparsely encoding a %d,%d image\n", pixelsWide, pixelsHigh);
1112  InitImages();
1113 
1114  flist = (float *)Mem_ClearedAlloc( (numQuadCels+1) *sizeof(float) );
1115  ilist = (int *)Mem_ClearedAlloc( (numQuadCels+1) *sizeof(int ) );
1116 
1117 
1118  fsize = 56*1024;
1119  if (theRoQ->NumberOfFrames()>2) {
1120  if (previousImage[0]) fsize = theRoQ->NormalFrameSize(); else fsize = theRoQ->FirstFrameSize();
1121  if (theRoQ->HasSound() && fsize > 6000 && previousImage[0]) fsize = 6000;
1122  }
1123  fsize += (slop/50);
1124  if (fsize > 64000) {
1125  fsize = 64000;
1126  }
1127  if (previousImage[0] && fsize > theRoQ->NormalFrameSize()*2) {
1128  fsize = theRoQ->NormalFrameSize()*2;
1129  }
1130  dxMean = dyMean = 0;
1131  if (previousImage[0]) wtype = 1; else wtype = 0;
1132 
1133  for( i=0; i<numQuadCels; i++ ) {
1134  for(j=0;j<DEAD;j++) qStatus[i].snr[j] = 9999;
1135  qStatus[i].mark = false;
1136  if ( qStatus[i].size == osize ) {
1137  if (previousImage[0]) {
1138  GetData( idataA, qStatus[i].size, qStatus[i].xat, qStatus[i].yat, image );
1139  GetData( idataB, qStatus[i].size, qStatus[i].xat, qStatus[i].yat, previousImage[whichFrame&1] );
1140  qStatus[i].snr[MOT] = Snr( idataA, idataB, qStatus[i].size );
1141  if (ComputeMotionBlock( idataA, idataB, qStatus[i].size ) && !theRoQ->IsLastFrame()) {
1142  qStatus[i].mark = true;
1143  }
1144  if (!qStatus[i].mark) {
1145  FvqData( idataA, qStatus[i].size, qStatus[i].xat, qStatus[i].yat, &qStatus[i], false );
1146  }
1147  }
1148  LowestQuad( &qStatus[i], &qStatus[i].status, &qStatus[i].rsnr, wtype );
1149  if (qStatus[i].rsnr < 9999)
1150  theRoQ->MarkQuadx( qStatus[i].xat, qStatus[i].yat, qStatus[i].size, qStatus[i].rsnr, qStatus[i].status );
1151  } else {
1152  if ( qStatus[i].size < osize ) {
1153  qStatus[i].status = 0;
1154  qStatus[i].size = 0;
1155  } else {
1156  qStatus[i].status = DEP;
1157  qStatus[i].rsnr = 0;
1158  }
1159  }
1160  }
1161 //
1162 // the quad is complete, so status can now be used for quad decomposition
1163 // the first thing to do is to set it up for all the 4x4 cels to get output
1164 // and then recurse from there to see what's what
1165 //
1166  sRMSE = GetCurrentRMSE( qStatus );
1167 
1168  if (theRoQ->IsQuiet() == false) {
1169  common->Printf("sparseEncode: rmse of quad0 is %f, size is %d (meant to be %d)\n", sRMSE, GetCurrentQuadOutputSize(qStatus), fsize );
1170  }
1171 
1172  onf = 0;
1173  for(i=0;i<numQuadCels;i++) {
1174  if ( qStatus[i].size && qStatus[i].status != DEP) {
1175  flist[onf] = qStatus[i].rsnr;
1176  ilist[onf] = i;
1177  onf++;
1178  }
1179  }
1180 
1181  Sort( flist, ilist, onf );
1182  Segment( ilist, flist, onf, GetCurrentRMSE( qStatus ));
1183 
1184  temp = dxMean = dyMean = 0;
1185  /*
1186  for( i=0; i<numQuadCels; i++ ) {
1187  if (qStatus[i].size && qStatus[i].status == FCC) {
1188  dxMean += (qStatus[i].domain >> 8 ) - 128;
1189  dyMean += (qStatus[i].domain & 0xff) - 128;
1190  temp++;
1191  }
1192  }
1193  if (temp) { dxMean /= temp; dyMean /= temp; }
1194  */
1195  common->Printf("sparseEncode: dx/dy mean is %d,%d\n", dxMean, dyMean);
1196 
1197  numredo = 0;
1198  detail = false;
1199  if (codebookmade && whichFrame>4) fsize -= 256;
1200  temp = 0;
1201  for( i=0; i<numQuadCels; i++ ) {
1202  if ( qStatus[i].size == osize && qStatus[i].mark == false && qStatus[i].snr[MOT] > 0 ) {
1203  GetData( idataA, qStatus[i].size, qStatus[i].xat, qStatus[i].yat, image );
1204  if (osize == 8) VqData8( idataA, &qStatus[i] );
1205  if (previousImage[0]) {
1206  int dx,dy;
1207  dx = (qStatus[i].domain >> 8 ) - 128 - dxMean + 8;
1208  dy = (qStatus[i].domain & 0xff) - 128 - dyMean + 8;
1209  if (dx<0||dx>15||dy<0||dy>15) {
1210  qStatus[i].snr[FCC] = 9999;
1211  temp++;
1212  FvqData( idataA, qStatus[i].size, qStatus[i].xat, qStatus[i].yat, &qStatus[i], true );
1213  dx = (qStatus[i].domain >> 8 ) - 128 - dxMean + 8;
1214  dy = (qStatus[i].domain & 0xff) - 128 - dyMean + 8;
1215  if ((dx<0||dx>15||dy<0||dy>15)&&qStatus[i].snr[FCC]!=9999&&qStatus[i].status==FCC) {
1216  common->Printf("sparseEncode: something is wrong here, dx/dy is %d,%d after being clamped\n", dx, dy);
1217  common->Printf("xat: %d\n", qStatus[i].xat);
1218  common->Printf("yat: %d\n", qStatus[i].yat);
1219  common->Printf("size %d\n", qStatus[i].size);
1220  common->Printf("type: %d\n", qStatus[i].status);
1221  common->Printf("mot: %04x\n", qStatus[i].domain);
1222  common->Printf("motsnr: %0f\n", qStatus[i].snr[FCC]);
1223  common->Printf("rmse: %0f\n", qStatus[i].rsnr);
1224  common->Error("need to go away now\n");
1225  }
1226  }
1227  }
1228  LowestQuad( &qStatus[i], &qStatus[i].status, &qStatus[i].rsnr, wtype );
1229  theRoQ->MarkQuadx( qStatus[i].xat, qStatus[i].yat, qStatus[i].size, qStatus[i].rsnr, qStatus[i].status );
1230  /*
1231  if (qStatus[i].status==FCC && qStatus[i].snr[FCC]>qStatus[i].snr[SLD]) {
1232  common->Printf("sparseEncode: something is wrong here\n");
1233  common->Printf("xat: %d\n", qStatus[i].xat);
1234  common->Printf("yat: %d\n", qStatus[i].yat);
1235  common->Printf("size %d\n", qStatus[i].size);
1236  common->Printf("type: %d\n", qStatus[i].status);
1237  common->Printf("mot: %04x\n", qStatus[i].domain);
1238  common->Printf("motsnr: %0f\n", qStatus[i].snr[FCC]);
1239  common->Printf("sldsnr: %0f\n", qStatus[i].snr[SLD]);
1240  common->Printf("rmse: %0f\n", qStatus[i].rsnr);
1241  //common->Error("need to go away now\n");
1242  }
1243  */
1244  }
1245  }
1246 
1247  if (theRoQ->IsQuiet() == false) {
1248  common->Printf("sparseEncode: rmse of quad0 is %f, size is %d (meant to be %d)\n", GetCurrentRMSE( qStatus ), GetCurrentQuadOutputSize( qStatus ), fsize );
1249  common->Printf("sparseEncode: %d outside fcc limits\n", temp);
1250  }
1251 
1252  onf = 0;
1253  for(i=0;i<numQuadCels;i++) {
1254  if ( qStatus[i].size && qStatus[i].status != DEP) {
1255  flist[onf] = qStatus[i].rsnr;
1256  ilist[onf] = i;
1257  onf++;
1258  }
1259  }
1260 
1261  Sort(flist, ilist, onf );
1262 
1263  ong = 0; detail = false;
1264 
1265  while ( GetCurrentQuadOutputSize(qStatus) < fsize && ong < onf && flist[ong] > 0 && qStatus[ilist[ong]].mark == false) {
1266 // badsnr = [self getCurrentRMSE: qStatus];
1267  osize = AddQuad( qStatus, ilist[ong++] );
1268 // if ([self getCurrentRMSE: qStatus] >= badsnr) {
1269 // break;
1270 // }
1271  }
1272 
1273  if ( GetCurrentQuadOutputSize( qStatus ) < fsize) {
1274  ong = 0;
1275  while ( GetCurrentQuadOutputSize(qStatus) < fsize && ong < onf) {
1276 // badsnr = [self getCurrentRMSE: qStatus];
1277  i = ilist[ong++];
1278  if (qStatus[i].mark) {
1279  detail = false;
1280  qStatus[i].mark = false;
1281  GetData( idataA, qStatus[i].size, qStatus[i].xat, qStatus[i].yat, image );
1282  if (qStatus[i].size == 8) VqData8( idataA, &qStatus[i] );
1283  if (qStatus[i].size == 4) VqData4( idataA, &qStatus[i] );
1284  if (qStatus[i].size == 4) VqData2( idataA, &qStatus[i] );
1285  if (previousImage[0]) {
1286  FvqData( idataA, qStatus[i].size, qStatus[i].xat, qStatus[i].yat, &qStatus[i], true );
1287  }
1288  LowestQuad( &qStatus[i], &qStatus[i].status, &qStatus[i].rsnr, wtype );
1289  if (qStatus[i].rsnr <= MIN_SNR) {
1290  break;
1291  }
1292  theRoQ->MarkQuadx( qStatus[i].xat, qStatus[i].yat, qStatus[i].size, qStatus[i].rsnr, qStatus[i].status );
1293  }
1294 // if ([self getCurrentRMSE: qStatus] >= badsnr) {
1295 // break;
1296 // }
1297  }
1298  ong = 0;
1299  while ( GetCurrentQuadOutputSize( qStatus ) < fsize && ong < onf && flist[ong] > 0) {
1300 // badsnr = [self getCurrentRMSE: qStatus];
1301  i = ilist[ong++];
1302 // if (qStatus[i].rsnr <= MIN_SNR) {
1303 // break;
1304 // }
1305  detail = true;
1306  osize = AddQuad( qStatus, i );
1307 // if ([self getCurrentRMSE: qStatus] >= badsnr) {
1308 // break;
1309 // }
1310  }
1311  }
1312 
1313  common->Printf("sparseEncode: rmse of frame %d is %f, size is %d\n", whichFrame, GetCurrentRMSE(qStatus), GetCurrentQuadOutputSize(qStatus) );
1314 
1315  if (previousImage[0])
1316  fsize = theRoQ->NormalFrameSize();
1317  else
1318  fsize = theRoQ->FirstFrameSize();
1319 
1320  slop += (fsize - GetCurrentQuadOutputSize(qStatus));
1321 
1322  if (theRoQ->IsQuiet() == false) {
1323  for(i=0;i<DEAD;i++) num[i] = 0;
1324  j = 0;
1325  for( i=0; i<numQuadCels; i++ ) {
1326  if (qStatus[i].size == 8 && qStatus[i].status) {
1327  if (qStatus[i].status < DEAD) num[qStatus[i].status]++; j++;
1328  }
1329  }
1330  common->Printf("sparseEncode: for 08x08 CCC = %d, FCC = %d, MOT = %d, SLD = %d, PAT = %d\n", num[CCC], num[FCC], num[MOT], num[SLD], num[PAT]);
1331 
1332  for(i=0;i<DEAD;i++) num[i] = 0;
1333  for( i=0; i<numQuadCels; i++ ) {
1334  if (qStatus[i].size == 4 && qStatus[i].status) {
1335  if (qStatus[i].status < DEAD) num[qStatus[i].status]++; j++;
1336  }
1337  }
1338  common->Printf("sparseEncode: for 04x04 CCC = %d, FCC = %d, MOT = %d, SLD = %d, PAT = %d\n", num[CCC], num[FCC], num[MOT], num[SLD], num[PAT]);
1339 
1340  common->Printf("sparseEncode: average RMSE = %f, numActiveQuadCels = %d, estSize = %d, slop = %d \n", GetCurrentRMSE(qStatus), j, GetCurrentQuadOutputSize(qStatus), slop);
1341  }
1342 
1345 
1346  Mem_Free(idataA);
1347  Mem_Free(idataB);
1348  Mem_Free(flist);
1349  Mem_Free(ilist);
1350  if (newImage) delete newImage;
1351 
1352  whichFrame++;
1353 }
1354 
1356 {
1357 int i, j, osize, fsize, num[DEAD+1], *ilist, wtype;
1358 float *flist, sRMSE;
1359 byte *idataA, *idataB;
1360 
1361  osize = 8;
1362 
1363  image = theRoQ->CurrentImage();
1364  newImage = 0;
1365 
1366  pixelsHigh = image->pixelsHigh();
1367  pixelsWide = image->pixelsWide();
1368 
1369  dimension2 = 12; dimension4 = 48;
1370  if (image->hasAlpha()&&(theRoQ->ParamNoAlpha() == false)) { dimension2 = 16; dimension4 = 64; }
1371 
1372  idataA = (byte *)Mem_Alloc( 16*16*4 );
1373  idataB = (byte *)Mem_Alloc( 16*16*4 );
1374 
1375  if (!previousImage[0]) common->Printf("sparseEncode: sparsely encoding a %d,%d image\n", pixelsWide, pixelsHigh);
1376  InitImages();
1377 
1378  flist = (float *)Mem_ClearedAlloc( (numQuadCels+1) * sizeof(float) );
1379  ilist = (int *)Mem_ClearedAlloc( (numQuadCels+1) * sizeof(int ) );
1380 
1381 
1382  fsize = 56*1024;
1383  if (theRoQ->NumberOfFrames()>2) {
1384  if (previousImage[0]) fsize = theRoQ->NormalFrameSize(); else fsize = theRoQ->FirstFrameSize();
1385  if (theRoQ->HasSound() && fsize > 6000 && previousImage[0]) fsize = 6000;
1386  }
1387 
1388  dxMean = dyMean = 0;
1389  if (previousImage[0]) wtype = 1; else wtype = 0;
1390 
1391  for( i=0; i<numQuadCels; i++ ) {
1392  for(j=0;j<DEAD;j++) qStatus[i].snr[j] = 9999;
1393  qStatus[i].mark = false;
1394  if ( qStatus[i].size == osize ) {
1395  if (previousImage[0]) {
1396  GetData( idataA, qStatus[i].size, qStatus[i].xat, qStatus[i].yat, image );
1397  GetData( idataB, qStatus[i].size, qStatus[i].xat, qStatus[i].yat, previousImage[whichFrame&1] );
1398  qStatus[i].snr[MOT] = Snr( idataA, idataB, qStatus[i].size );
1399  }
1400  LowestQuad( &qStatus[i], &qStatus[i].status, &qStatus[i].rsnr, wtype );
1401  if (qStatus[i].rsnr < 9999)
1402  theRoQ->MarkQuadx( qStatus[i].xat, qStatus[i].yat, qStatus[i].size, qStatus[i].rsnr, qStatus[i].status );
1403  } else {
1404  if ( qStatus[i].size < osize ) {
1405  qStatus[i].status = 0;
1406  qStatus[i].size = 0;
1407  } else {
1408  qStatus[i].status = DEP;
1409  qStatus[i].rsnr = 0;
1410  }
1411  }
1412  }
1413 //
1414 // the quad is complete, so status can now be used for quad decomposition
1415 // the first thing to do is to set it up for all the 4x4 cels to get output
1416 // and then recurse from there to see what's what
1417 //
1418  sRMSE = GetCurrentRMSE( qStatus );
1419 
1420  common->Printf("sparseEncode: rmse of frame %d is %f, size is %d\n", whichFrame, sRMSE, GetCurrentQuadOutputSize( qStatus ) );
1421 
1422 
1423  if (theRoQ->IsQuiet() == false) {
1424  for(i=0;i<DEAD;i++) num[i] = 0;
1425  j = 0;
1426  for( i=0; i<numQuadCels; i++ ) {
1427  if (qStatus[i].size == 8 && qStatus[i].status) {
1428  if (qStatus[i].status < DEAD) num[qStatus[i].status]++; j++;
1429  }
1430  }
1431  common->Printf("sparseEncode: for 08x08 CCC = %d, FCC = %d, MOT = %d, SLD = %d, PAT = %d\n", num[CCC], num[FCC], num[MOT], num[SLD], num[PAT]);
1432 
1433  for(i=0;i<DEAD;i++) num[i] = 0;
1434  for( i=0; i<numQuadCels; i++ ) {
1435  if (qStatus[i].size == 4 && qStatus[i].status) {
1436  if (qStatus[i].status < DEAD) num[qStatus[i].status]++; j++;
1437  }
1438  }
1439  common->Printf("sparseEncode: for 04x04 CCC = %d, FCC = %d, MOT = %d, SLD = %d, PAT = %d\n", num[CCC], num[FCC], num[MOT], num[SLD], num[PAT]);
1440 
1441  common->Printf("sparseEncode: average RMSE = %f, numActiveQuadCels = %d, estSize = %d \n", GetCurrentRMSE(qStatus), j, GetCurrentQuadOutputSize(qStatus));
1442  }
1443 
1446 
1447  Mem_Free(idataA);
1448  Mem_Free(idataB);
1449  Mem_Free(flist);
1450  Mem_Free(ilist);
1451  if (newImage) delete newImage;
1452 
1453  whichFrame++;
1454 }
1455 
1456 void codec::VQ( const int numEntries, const int dimension, const unsigned char *vectors, float *import, VQDATA **codebook, const bool optimize ) {
1457  int startMsec = Sys_Milliseconds();
1458 
1459  if (numEntries <= 256) {
1460  //
1461  // copy the entries into the codebooks
1462  //
1463  for( int i=0; i<numEntries; i++ ) {
1464  for( int j=0; j<dimension; j++ ) {
1465  codebook[i][j] = vectors[j+i*dimension];
1466  }
1467  }
1468  return;
1469  }
1470  //
1471  // okay, we need to wittle this down to less than 256 entries
1472  //
1473 
1474  // get rid of identical entries
1475 
1476  int i, j, x, ibase, jbase;
1477 
1478  bool *inuse = (bool *)_alloca( numEntries * sizeof(bool) );
1479  float *snrs = (float *)_alloca( numEntries * sizeof(float) );
1480  int *indexes = (int *)_alloca( numEntries * sizeof(int) );
1481  int *indexet = (int *)_alloca( numEntries * sizeof(int) );
1482 
1483  int numFinalEntries = numEntries;
1484  for( i=0; i<numEntries; i++ ) {
1485  inuse[i] = true;
1486  snrs[i] = -1.0f;
1487  indexes[i] = -1;
1488  indexet[i] = -1;
1489  }
1490 
1491  for( i=0; i<numEntries-1; i++ ) {
1492  for( j=i+1; j<numEntries; j++ ) {
1493  if (inuse[i] && inuse[j]) {
1494  if (!memcmp( &vectors[i*dimension], &vectors[j*dimension], dimension)) {
1495  inuse[j] = false;
1496  numFinalEntries--;
1497  import[i] += import[j];
1498  }
1499  }
1500  }
1501  }
1502 
1503  common->Printf("VQ: has %d entries to process\n", numFinalEntries );
1504 
1505  //
1506  // are we done?
1507  //
1508  int end;
1509  if (numFinalEntries > 256) {
1510  //
1511  // find the closest two and eliminate one
1512  //
1513  double bestDist = HUGE;
1514  double dist, simport;
1515  int bestIndex = -1;
1516  int bestOtherIndex = 0;
1517  int aentries = 0;
1518  for( i=0; i<numEntries-1; i++ ) {
1519  if (inuse[i]) {
1520  end = numEntries;
1521  if (optimize) {
1522  if (numFinalEntries>8192) {
1523  end = i+32;
1524  } else if (numFinalEntries>4096) {
1525  end = i+64;
1526  } else if (numFinalEntries>2048) {
1527  end = i+128;
1528  } else if (numFinalEntries>1024) {
1529  end = i+256;
1530  } else if (numFinalEntries>512) {
1531  end = i+512;
1532  }
1533  if (end>numEntries) {
1534  end = numEntries;
1535  }
1536  }
1537  ibase = i*dimension;
1538  for( j=i+1; j<end; j++ ) {
1539  if (inuse[j]) {
1540  dist = 0.0;
1541  jbase = j*dimension;
1542  for( x=0; x<dimension; x+=3 ) {
1543 #if 0
1544  r0 = (float)vectors[ibase+x];
1545  r1 = (float)vectors[jbase+x];
1546  g0 = (float)vectors[ibase+x+1];
1547  g1 = (float)vectors[jbase+x+1];
1548  b0 = (float)vectors[ibase+x+2];
1549  b1 = (float)vectors[jbase+x+2];
1550  dist += idMath::Sqrt16( (r0-r1)*(r0-r1) + (g0-g1)*(g0-g1) + (b0-b1)*(b0-b1) );
1551 #else
1552  // JDC: optimization
1553  int dr = vectors[ibase+x] - vectors[jbase+x];
1554  int dg = vectors[ibase+x+1] - vectors[jbase+x+1];
1555  int db = vectors[ibase+x+2] - vectors[jbase+x+2];
1556  dist += idMath::Sqrt16( dr * dr + dg * dg + db * db );
1557 #endif
1558  }
1559  simport = import[i] * import[j];
1560  dist *= simport;
1561  if ( dist < bestDist ) {
1562  bestDist = dist;
1563  bestIndex = i;
1564  bestOtherIndex = j;
1565  }
1566  }
1567  }
1568  snrs[aentries] = bestDist;
1569  indexes[aentries] = bestIndex;
1570  indexet[aentries] = bestOtherIndex;
1571  aentries++;
1572  }
1573  }
1574 
1575  //
1576  // until we have reduced it to 256 entries, find one to toss
1577  //
1578  do {
1579  bestDist = HUGE;
1580  bestIndex = -1;
1581  bestOtherIndex = -1;
1582  if (optimize) {
1583  for( i=0; i<aentries; i++ ) {
1584  if (inuse[indexes[i]] && inuse[indexet[i]] ) {
1585  if ( snrs[i] < bestDist ) {
1586  bestDist = snrs[i];
1587  bestIndex = indexes[i];
1588  bestOtherIndex = indexet[i];
1589  }
1590  }
1591  }
1592  }
1593  if (bestIndex == -1 || !optimize) {
1594  bestDist = HUGE;
1595  bestIndex = -1;
1596  bestOtherIndex = 0;
1597  aentries = 0;
1598  for( i=0; i<numEntries-1; i++ ) {
1599  if (!inuse[i]) {
1600  continue;
1601  }
1602  end = numEntries;
1603  if (optimize) {
1604  if (numFinalEntries>8192) {
1605  end = i+32;
1606  } else if (numFinalEntries>4096) {
1607  end = i+64;
1608  } else if (numFinalEntries>2048) {
1609  end = i+128;
1610  } else if (numFinalEntries>1024) {
1611  end = i+256;
1612  } else if (numFinalEntries>512) {
1613  end = i+512;
1614  }
1615  }
1616  if (end>numEntries) {
1617  end = numEntries;
1618  }
1619  ibase = i*dimension;
1620  for( j=i+1; j<end; j++ ) {
1621  if ( !inuse[j]) {
1622  continue;
1623  }
1624  dist = 0.0;
1625  jbase = j*dimension;
1626  simport = import[i] * import[j];
1627  float scaledBestDist = bestDist / simport;
1628  for( x=0; x<dimension; x+=3 ) {
1629 #if 0
1630  r0 = (float)vectors[ibase+x];
1631  r1 = (float)vectors[jbase+x];
1632  g0 = (float)vectors[ibase+x+1];
1633  g1 = (float)vectors[jbase+x+1];
1634  b0 = (float)vectors[ibase+x+2];
1635  b1 = (float)vectors[jbase+x+2];
1636  dist += idMath::Sqrt16( (r0-r1)*(r0-r1) + (g0-g1)*(g0-g1) + (b0-b1)*(b0-b1) );
1637 #else
1638  // JDC: optimization
1639  int dr = vectors[ibase+x] - vectors[jbase+x];
1640  int dg = vectors[ibase+x+1] - vectors[jbase+x+1];
1641  int db = vectors[ibase+x+2] - vectors[jbase+x+2];
1642  dist += idMath::Sqrt16( dr * dr + dg * dg + db * db );
1643  if ( dist > scaledBestDist ) {
1644  break;
1645  }
1646 #endif
1647  }
1648  dist *= simport;
1649  if ( dist < bestDist ) {
1650  bestDist = dist;
1651  bestIndex = i;
1652  bestOtherIndex = j;
1653  }
1654  }
1655  snrs[aentries] = bestDist;
1656  indexes[aentries] = bestIndex;
1657  indexet[aentries] = bestOtherIndex;
1658  aentries++;
1659  }
1660  }
1661  //
1662  // and lose one
1663  //
1664  inuse[bestIndex] = false;
1665  numFinalEntries--;
1666  import[bestOtherIndex] += import[bestIndex];
1667  if ((numFinalEntries&511)==0) {
1668  common->Printf("VQ: has %d entries to process\n", numFinalEntries );
1669  session->UpdateScreen();
1670  }
1671  } while (numFinalEntries > 256);
1672  }
1673  //
1674  // copy the entries into the codebooks
1675  //
1676  int onEntry = 0;
1677  for( i=0; i<numEntries; i++ ) {
1678  if (inuse[i]) {
1679  ibase = i*dimension;
1680  for( x=0; x<dimension; x++ ) {
1681  codebook[onEntry][x] = vectors[ibase + x];
1682  }
1683  if (onEntry == 0) {
1684  common->Printf("First vq = %d\n ", i);
1685  }
1686  if (onEntry == 255) {
1687  common->Printf("last vq = %d\n", i);
1688  }
1689  onEntry++;
1690  }
1691  }
1692 
1693  int endMsec = Sys_Milliseconds();
1694  common->Printf( "VQ took %i msec\n", endMsec - startMsec );
1695 }
1696 
GLubyte g
Definition: glext.h:4662
int dyMean
Definition: codec.h:89
virtual idFile * OpenFileRead(const char *relativePath, bool allowCopyFiles=true, const char *gamedir=NULL)=0
void SetPreviousImage(const char *filename, NSBitmapImageRep *timage)
Definition: codec.cpp:362
NSBitmapImageRep * previousImage[2]
Definition: codec.h:80
int dimension2
Definition: codec.h:98
#define STRIDE_FACTOR
VQDATA ** codebook4
Definition: codec.h:104
int numQuadCels
Definition: codec.h:81
bool IsLastFrame(void)
Definition: roq.cpp:63
int slop
Definition: codec.h:83
bool used2[256]
Definition: codec.h:96
int codebooksize
Definition: codec.h:90
bool IsQuiet(void)
Definition: roq.cpp:58
float GetCurrentRMSE(quadcel *pquad)
Definition: codec.cpp:1001
void SparseEncode(void)
Definition: codec.cpp:1091
#define PAT
Definition: quaddefs.h:37
float snr[DEAD+1]
Definition: quaddefs.h:104
#define BMULT
Definition: gdefs.h:59
roq * theRoQ
Definition: roq.cpp:34
int status
Definition: quaddefs.h:102
void MakePreviousImage(quadcel *pquad)
Definition: codec.cpp:385
#define BQEMULT
Definition: gdefs.h:66
GLenum GLint GLint y
Definition: glext.h:2849
#define MOT
Definition: quaddefs.h:38
#define GIEMULT
Definition: gdefs.h:63
int ComputeMotionBlock(byte *old, byte *bnew, int size)
Definition: codec.cpp:771
int Sys_Milliseconds(void)
case const int
Definition: Callbacks.cpp:52
#define VQDATA
Definition: codec.h:39
idFileSystem * fileSystem
Definition: FileSystem.cpp:500
case const float
Definition: Callbacks.cpp:62
GLenum GLsizei GLenum GLenum const GLvoid * image
Definition: glext.h:2855
void WriteCodeBook(byte *codebook)
Definition: roq.cpp:622
NSBitmapImageRep * newImage
Definition: codec.h:79
byte * luti
Definition: codec.h:102
#define DEAD
Definition: quaddefs.h:39
int NumberOfFrames(void)
Definition: roq.cpp:840
#define GMULT
Definition: gdefs.h:58
void GetData(unsigned char *iData, int qSize, int startX, int startY, NSBitmapImageRep *bitmap)
Definition: codec.cpp:905
float rsnr
Definition: quaddefs.h:88
GLuint src
Definition: glext.h:5390
GLenum GLsizei len
Definition: glext.h:3472
static float Sqrt16(float x)
Definition: Math.h:298
#define RGBADIST(src0, src1)
Definition: gdefs.h:51
#define RIEMULT
Definition: gdefs.h:61
#define DEP
Definition: quaddefs.h:33
void VqData2(byte *cel, quadcel *pquad)
Definition: codec.cpp:708
GLenum GLint x
Definition: glext.h:2849
int i
Definition: process.py:33
GLuint GLuint num
Definition: glext.h:5390
int dimension4
Definition: codec.h:99
bool used4[256]
Definition: codec.h:97
GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte * bitmap
Definition: qgl.h:183
bool detail
Definition: codec.h:84
byte size
Definition: quaddefs.h:78
Definition: File.h:50
int MotMeanY(void)
Definition: codec.cpp:1086
#define FCC
Definition: quaddefs.h:34
void InitQStatus()
Definition: codec.cpp:627
const float MOTION_MIN
Definition: codec.h:33
GLuint dst
Definition: glext.h:5285
void VqData4(byte *cel, quadcel *pquad)
Definition: codec.cpp:679
void VQ(const int numEntries, const int dimension, const unsigned char *vectors, float *snr, VQDATA **codebook, const bool optimize)
Definition: codec.cpp:1456
int pixelsHigh
Definition: codec.h:94
int AddQuad(quadcel *pquad, int lownum)
Definition: codec.cpp:1018
int codebookmade
Definition: codec.h:95
GLuint index
Definition: glext.h:3476
int pixelsWide
Definition: codec.h:93
const GLubyte * c
Definition: glext.h:4677
#define SLD
Definition: quaddefs.h:36
codec()
Definition: codec.cpp:39
bool Scaleable(void)
Definition: roq.cpp:68
const float MIN_SNR
Definition: codec.h:34
const char * CurrentFilename(void)
Definition: roq.cpp:108
GLuint GLuint end
Definition: glext.h:2845
int GetCurrentQuadOutputSize(quadcel *pquad)
Definition: codec.cpp:978
idCommon * common
Definition: Common.cpp:206
int initRGBtab
Definition: codec.h:86
void LowestQuad(quadcel *qtemp, int *status, float *snr, int bweigh)
Definition: codec.cpp:948
void FvqData(byte *bitmap, int size, int realx, int realy, quadcel *pquad, bool clamp)
Definition: codec.cpp:788
virtual idFile * OpenFileWrite(const char *relativePath, const char *basePath="fs_savepath")=0
virtual int Read(void *buffer, int len)
Definition: File.cpp:179
void QuadX(int startX, int startY, int quadSize)
Definition: codec.cpp:601
void Segment(int *alist, float *flist, int numElements, float rmse)
Definition: codec.cpp:114
word patten[5]
Definition: quaddefs.h:100
#define CCC
Definition: quaddefs.h:35
#define BIEMULT
Definition: gdefs.h:65
void Mem_Free(void *ptr)
Definition: Heap.cpp:1087
int MotMeanX(void)
Definition: codec.cpp:1081
GLubyte GLubyte GLubyte a
Definition: glext.h:4662
virtual void UpdateScreen(bool outOfSequence=true)=0
virtual void Printf(const char *fmt,...) id_attribute((format(printf
quadcel * qStatus
Definition: codec.h:87
GLdouble GLdouble GLdouble y2
Definition: qgl.h:415
int FirstFrameSize(void)
Definition: roq.cpp:98
NSBitmapImageRep * CurrentImage(void)
Definition: roq.cpp:835
word domain
Definition: quaddefs.h:99
bool HasSound(void)
Definition: roq.cpp:88
GLubyte GLubyte b
Definition: glext.h:4662
int dxMean
Definition: codec.h:88
GLfloat GLfloat GLfloat GLfloat nx
Definition: glext.h:4670
void MarkQuadx(int xat, int yat, int size, float cerror, int choice)
Definition: roq.cpp:832
void Sort(float *list, int *intIndex, int numElements)
Definition: codec.cpp:83
GLdouble GLdouble GLdouble r
Definition: glext.h:2951
int onQuad
Definition: codec.h:85
~codec()
Definition: codec.cpp:63
int BestCodeword(unsigned char *tempvector, int dimension, VQDATA **codebook)
Definition: codec.cpp:321
int overAmount
Definition: codec.h:92
tuple f
Definition: idal.py:89
const int MAXSIZE
Definition: Cinematic.cpp:119
unsigned char byte
Definition: Lib.h:75
void EncodeNothing(void)
Definition: codec.cpp:1355
GLsizeiptr size
Definition: glext.h:3112
VQDATA ** codebook2
Definition: codec.h:103
GLdouble y1
Definition: qgl.h:415
virtual int Write(const void *buffer, int len)
Definition: File.cpp:189
int NormalFrameSize(void)
Definition: roq.cpp:103
const int MINSIZE
Definition: Cinematic.cpp:120
void * Mem_ClearedAlloc(const int size)
Definition: Heap.cpp:1149
float glimit(const float val)
Definition: codec.cpp:33
byte luty[256]
Definition: codec.h:101
word xat
Definition: quaddefs.h:79
GLsizei stride
Definition: glext.h:3035
int whichFrame
Definition: codec.h:82
void * Mem_Alloc(const int size)
Definition: Heap.cpp:1067
GLint j
Definition: qgl.h:264
void IRGBtab(void)
Definition: codec.cpp:745
void WriteFrame(quadcel *pquad)
Definition: roq.cpp:627
idSession * session
Definition: Session.cpp:48
void InitImages(void)
Definition: codec.cpp:564
virtual void CloseFile(idFile *f)=0
virtual void Error(const char *fmt,...) id_attribute((format(printf
bool ParamNoAlpha(void)
Definition: roq.cpp:73
#define RMULT
Definition: gdefs.h:57
#define GQEMULT
Definition: gdefs.h:64
#define RQEMULT
Definition: gdefs.h:62
float Snr(byte *old, byte *bnew, int size)
Definition: codec.cpp:750
word yat
Definition: quaddefs.h:80
byte * bitmapData(void)
int sprintf(idStr &string, const char *fmt,...)
Definition: Str.cpp:1528
void VqData8(byte *cel, quadcel *pquad)
Definition: codec.cpp:643
bool mark
Definition: quaddefs.h:103
GLint fsize
Definition: glext.h:5180