Ticket #8594: encode_dxa.patch
File encode_dxa.patch, 21.7 KB (added by , 18 years ago) |
---|
-
encode_dxa.cpp
41 41 42 42 static CompressMode gCompMode = kMP3Mode; 43 43 44 enum ScaleMode { S_NONE, S_INTERLACED, S_DOUBLE }; 45 46 struct DiffStruct { 47 unsigned short map; 48 int count; 49 byte pixels[BLOCKW*BLOCKH]; 50 }; 51 44 52 class DxaEncoder { 45 53 private: 46 54 FILE *_dxa; 47 int _width, _height, _framerate, _framecount ;55 int _width, _height, _framerate, _framecount, _workheight; 48 56 uint8 *_prevframe, *_prevpalette; 57 ScaleMode _scaleMode; 49 58 50 bool m12blocksAreEqual(byte *frame, int x, int y, int x2, int y2); 51 bool m12blockIsSolidColor(byte *frame, int x, int y, byte &color); 52 void m12blockDelta(byte *frame, int x, int y, unsigned short &diffMap, int &diffCount, byte diffPix[]); 53 bool m12motionVector(byte *frame, int x, int y, int &mx, int &my); 54 uLong m12encode(byte *frame, byte *outbuf); 59 byte *_codeBuf, *_dataBuf, *_motBuf, *_maskBuf; 60 void grabBlock(byte *frame, int x, int y, int blockw, int blockh, byte *block); 61 bool m13blocksAreEqual(byte *frame, int x, int y, int x2, int y2, int w, int h); 62 bool m13blockIsSolidColor(byte *frame, int x, int y, int w, int h, byte &color); 63 void m13blockDelta(byte *frame, int x, int y, int x2, int y2, DiffStruct &diff); 64 bool m13motionVector(byte *frame, int x, int y, int w, int h, int &mx, int &my); 65 int m13countColors(byte *block, byte *pixels, unsigned long &code, int &codeSize); 66 uLong m13encode(byte *frame, byte *outbuf); 55 67 56 68 public: 57 DxaEncoder(char *filename, int width, int height, int f ps);69 DxaEncoder(char *filename, int width, int height, int framerate, ScaleMode scaleMode); 58 70 ~DxaEncoder(); 59 71 void writeHeader(); 60 72 void writeNULL(); 61 73 void writeFrame(uint8 *frame, uint8 *palette); 62 74 }; 63 75 64 DxaEncoder::DxaEncoder(char *filename, int width, int height, int framerate ) {76 DxaEncoder::DxaEncoder(char *filename, int width, int height, int framerate, ScaleMode scaleMode) { 65 77 _dxa = fopen(filename, "wb"); 66 78 _width = width; 67 79 _height = height; … … 69 81 _framecount = 0; 70 82 _prevframe = new uint8[_width * _height]; 71 83 _prevpalette = new uint8[768]; 84 _scaleMode = scaleMode; 85 _workheight = _scaleMode == S_NONE ? _height : _height / 2; 72 86 87 _codeBuf = new byte[_width * _height / 16]; 88 _dataBuf = new byte[_width * _height]; 89 _motBuf = new byte[_width * _height]; 90 _maskBuf = new byte[_width * _height]; 91 73 92 writeHeader(); 74 93 } 75 94 … … 80 99 81 100 fclose(_dxa); 82 101 102 delete[] _codeBuf; 103 delete[] _dataBuf; 104 delete[] _motBuf; 105 delete[] _maskBuf; 106 83 107 delete[] _prevframe; 84 108 delete[] _prevpalette; 85 109 } … … 88 112 //DEXA 89 113 uint8 version = 0; 90 114 115 /* remember the scaling mode */ 116 if (_scaleMode == S_INTERLACED) 117 version |= 0x80; 118 else if (_scaleMode == S_DOUBLE) 119 version |= 0x40; 120 91 121 writeUint32LE(_dxa, typeDEXA); 92 122 writeByte(_dxa, version); 93 123 … … 102 132 writeUint32LE(_dxa, typeNULL); 103 133 } 104 134 105 void DxaEncoder::writeFrame(uint8 *frame, uint8 *palette) { 135 void DxaEncoder::writeFrame(byte *frame, byte *palette) { 136 106 137 if (_framecount == 0 || memcmp(_prevpalette, palette, 768)) { 107 138 writeUint32LE(_dxa, typeCMAP); 108 139 fwrite(palette, 768, 1, _dxa); 109 110 140 memcpy(_prevpalette, palette, 768); 111 141 } else { 112 142 writeNULL(); 113 143 } 114 144 115 if (_framecount == 0 || memcmp(_prevframe, frame, _width * _ height)) {145 if (_framecount == 0 || memcmp(_prevframe, frame, _width * _workheight)) { 116 146 //FRAM 117 uint8compType;147 byte compType; 118 148 119 149 writeUint32LE(_dxa, typeFRAM); 120 150 121 151 if (_framecount == 0) 122 152 compType = 2; 123 153 else 124 //compType = 3; 125 compType = 12; 154 compType = 13; 126 155 127 156 switch (compType) { 157 128 158 case 2: 129 159 { 130 uLong outsize = _width * _height; 131 uint8 *outbuf = new uint8[outsize]; 132 133 compress2(outbuf, &outsize, frame, _width * _height, 9); 134 160 uLong outsize = _width * _workheight; 161 byte *outbuf = new byte[outsize]; 162 compress2(outbuf, &outsize, frame, _width * _workheight, 9); 135 163 writeByte(_dxa, compType); 136 137 164 writeUint32BE(_dxa, outsize); 138 139 165 fwrite(outbuf, outsize, 1, _dxa); 140 141 166 delete[] outbuf; 142 143 167 break; 144 168 } 145 case 3:146 {147 uLong outsize1 = _width * _height;148 uLong outsize2 = outsize1;149 uLong outsize;150 uint8 *outbuf;151 uint8 *outbuf1 = new uint8[outsize1];152 uint8 *outbuf2 = new uint8[outsize2];153 uint8 *xorbuf = new uint8[_width * _height];154 169 155 for (int i = 0; i < _width * _height; i++) 156 xorbuf[i] = _prevframe[i] ^ frame[i]; 170 case 13: 157 171 158 compress2(outbuf1, &outsize1, xorbuf, _width * _height, 9); 159 compress2(outbuf2, &outsize2, frame, _width * _height, 9); 172 { 160 173 161 if (outsize1 < outsize2) { 162 compType = 3; 163 outsize = outsize1; 164 outbuf = outbuf1; 165 } else { 166 compType = 2; 167 outsize = outsize2; 168 outbuf = outbuf2; 169 } 174 int r; 170 175 171 writeByte(_dxa, compType); 176 uLong frameoutsize; 177 byte *frameoutbuf; 172 178 173 writeUint32BE(_dxa, outsize); 179 byte *xorbuf = new byte[_width * _workheight]; 180 uLong xorsize_z = _width * _workheight; 181 byte *xorbuf_z = new byte[xorsize_z]; 174 182 175 fwrite(outbuf, outsize, 1, _dxa); 183 uLong rawsize_z = _width * _workheight; 184 byte *rawbuf_z = new byte[rawsize_z]; 176 185 177 delete[] outbuf1; 178 delete[] outbuf2; 179 delete[] xorbuf; 186 uLong m13size = _width * _workheight * 2; 187 byte *m13buf = new byte[m13size]; 188 uLong m13size_z = _width * _workheight; 189 byte *m13buf_z = new byte[m13size_z]; 180 190 181 break; 182 } 183 case 12: 191 /* encode the delta frame with mode 12 */ 192 m13size = m13encode(frame, m13buf); 184 193 185 { 194 /* create the xor buffer */ 195 for (int i = 0; i < _width * _workheight; i++) 196 xorbuf[i] = _prevframe[i] ^ frame[i]; 186 197 187 uLong outsize1 = _width * _height; 188 uLong outsize2 = outsize1; 189 uLong outsize3 = outsize1*2; 190 uLong outsize4 = outsize1; 191 uLong outsize; 192 uint8 *outbuf; 193 uint8 *outbuf1 = new uint8[outsize1]; 194 uint8 *outbuf2 = new uint8[outsize2]; 195 uint8 *outbuf3 = new uint8[outsize3]; 196 uint8 *outbuf4 = new uint8[outsize4]; 197 uint8 *xorbuf = new uint8[_width * _height]; 198 /* compress the m13 buffer */ 199 compress2(m13buf_z, &m13size_z, m13buf, m13size, 9); 198 200 199 for (int i = 0; i < _width * _height; i++) 200 xorbuf[i] = _prevframe[i] ^ frame[i]; 201 /* compress the xor buffer */ 202 xorsize_z = m13size_z; 203 r = compress2(xorbuf_z, &xorsize_z, xorbuf, _width * _workheight, 9); 204 if (r != Z_OK) xorsize_z = 0xFFFFFFF; 201 205 202 compress2(outbuf1, &outsize1, xorbuf, _width * _height, 9); 203 compress2(outbuf2, &outsize2, frame, _width * _height, 9); 204 if (outsize1 < outsize2) { 206 if (m13size_z < xorsize_z) { 207 compType = 13; 208 frameoutsize = m13size_z; 209 frameoutbuf = m13buf_z; 210 } else { 205 211 compType = 3; 206 outsize = outsize1; 207 outbuf = outbuf1; 208 } else { 209 compType = 2; 210 outsize = outsize2; 211 outbuf = outbuf2; 212 frameoutsize = xorsize_z; 213 frameoutbuf = xorbuf_z; 212 214 } 213 215 214 outsize3 = m12encode(frame, outbuf3); 216 /* compress the raw frame */ 217 rawsize_z = frameoutsize; 218 r = compress2(rawbuf_z, &rawsize_z, frame, _width * _workheight, 9); 219 if (r != Z_OK) rawsize_z = 0xFFFFFFF; 215 220 216 compress2(outbuf4, &outsize4, outbuf3, outsize3, 9); 221 if (rawsize_z < frameoutsize) { 222 compType = 2; 223 frameoutsize = rawsize_z; 224 frameoutbuf = rawbuf_z; 225 } 217 226 218 if (outsize4 < outsize) {219 compType = 12;220 outsize = outsize4;221 outbuf = outbuf4;222 }223 224 227 writeByte(_dxa, compType); 225 writeUint32BE(_dxa, outsize);226 fwrite( outbuf,outsize, 1, _dxa);228 writeUint32BE(_dxa, frameoutsize); 229 fwrite(frameoutbuf, frameoutsize, 1, _dxa); 227 230 228 delete[] outbuf1;229 delete[] outbuf2;230 delete[] outbuf3;231 delete[] outbuf4;231 delete[] xorbuf_z; 232 delete[] rawbuf_z; 233 delete[] m13buf_z; 234 delete[] m13buf; 232 235 delete[] xorbuf; 233 236 234 237 break; 235 238 } 236 239 } 237 240 238 memcpy(_prevframe, frame, _width * _ height);241 memcpy(_prevframe, frame, _width * _workheight); 239 242 240 243 } else { 241 244 writeNULL(); … … 244 247 _framecount++; 245 248 } 246 249 247 bool DxaEncoder::m1 2blocksAreEqual(byte *frame, int x, int y, int x2, int y2) {250 bool DxaEncoder::m13blocksAreEqual(byte *frame, int x, int y, int x2, int y2, int w, int h) { 248 251 byte *b1 = _prevframe + x + y * _width; 249 252 byte *b2 = frame + x2 + y2 * _width; 250 for (int yc = 0; yc < BLOCKH; yc++) {251 if (memcmp(b1, b2, BLOCKW))253 for (int yc = 0; yc < h; yc++) { 254 if (memcmp(b1, b2, w)) 252 255 return false; 253 256 b1 += _width; 254 257 b2 += _width; … … 256 259 return true; 257 260 } 258 261 259 bool DxaEncoder::m1 2blockIsSolidColor(byte *frame, int x, int y, byte &color) {262 bool DxaEncoder::m13blockIsSolidColor(byte *frame, int x, int y, int w, int h, byte &color) { 260 263 byte *b2 = frame + x + y * _width; 261 264 color = *b2; 262 for (int yc = 0; yc < BLOCKH; yc++) {263 for (int xc = 0; xc < BLOCKW; xc++) {265 for (int yc = 0; yc < h; yc++) { 266 for (int xc = 0; xc < w; xc++) { 264 267 if (b2[xc] != color) 265 268 return false; 266 269 } … … 269 272 return true; 270 273 } 271 274 272 void DxaEncoder::m1 2blockDelta(byte *frame, int x, int y, unsigned short &diffMap, int &diffCount, byte diffPix[]) {275 void DxaEncoder::m13blockDelta(byte *frame, int x, int y, int x2, int y2, DiffStruct &diff) { 273 276 byte *b1 = _prevframe + x + y * _width; 274 byte *b2 = frame + x + y* _width;275 diff Count = 0;276 diff Map = 0;277 byte *b2 = frame + x2 + y2 * _width; 278 diff.count = 0; 279 diff.map = 0; 277 280 for (int yc = 0; yc < BLOCKH; yc++) { 278 281 for (int xc = 0; xc < BLOCKW; xc++) { 279 282 if (b1[xc] != b2[xc]) { 280 diff Map = (diffMap << 1) | 1;281 diff Pix[diffCount++] = b2[xc];283 diff.map = (diff.map << 1) | 1; 284 diff.pixels[diff.count++] = b2[xc]; 282 285 } else { 283 diff Map = (diffMap << 1) | 0;286 diff.map = (diff.map << 1) | 0; 284 287 } 285 288 } 286 289 b1 += _width; … … 288 291 } 289 292 } 290 293 291 bool DxaEncoder::m1 2motionVector(byte *frame, int x, int y, int &mx, int &my) {294 bool DxaEncoder::m13motionVector(byte *frame, int x, int y, int w, int h, int &mx, int &my) { 292 295 int xmin = (0 > x-7) ? 0 : x-7; 293 296 int ymin = (0 > y-7) ? 0 : y-7; 294 297 int xmax = (_width < x+8) ? _width : x+8; 295 int ymax = (_ height < y+8) ? _height : y+8;298 int ymax = (_workheight < y+8) ? _height : y+8; 296 299 for (int yc = ymin; yc < ymax; yc++) { 297 300 for (int xc = xmin; xc < xmax; xc++) { 298 if (m1 2blocksAreEqual(frame, xc, yc, x, y)) {299 300 301 if (m13blocksAreEqual(frame, xc, yc, x, y, w, h)) { 302 mx = xc - x; 303 my = yc - y; 301 304 return true; 302 305 } 303 306 } … … 305 308 return false; 306 309 } 307 310 308 uLong DxaEncoder::m12encode(byte *frame, byte *outbuf) { 311 int DxaEncoder::m13countColors(byte *block, byte *pixels, unsigned long &code, int &codeSize) { 312 313 code = 0; 314 codeSize = 0; 315 316 /* count the number of colors used in this block */ 317 int count = 0; 318 int colTab[256]; 319 for (int i = 0; i < 256; i++) 320 colTab[i] = -1; 321 for (int i = 0; i < BLOCKW * BLOCKH; i++) { 322 if (colTab[block[i]] == -1) { 323 colTab[block[i]] = count; 324 pixels[count] = block[i]; 325 count++; 326 } 327 } 328 329 if (count <= 4) { 330 /* set the bitmask */ 331 if (count == 2) { 332 for (int i = 15; i >= 0; i--) { 333 code = (code << 1) | colTab[block[i]]; 334 } 335 codeSize = 2; 336 } else if (count == 4 || count == 3) { 337 for (int i = 15; i >= 0; i--) { 338 code = (code << 2) | colTab[block[i]]; 339 } 340 codeSize = 4; 341 } 342 } 343 344 return count; 345 346 } 347 348 /* grab the block */ 349 void DxaEncoder::grabBlock(byte *frame, int x, int y, int blockw, int blockh, byte *block) { 350 byte *b2 = (byte*)frame + x + y * _width; 351 for (int yc = 0; yc < blockh; yc++) { 352 memcpy(&block[yc*blockw], b2, blockw); 353 b2 += _width; 354 } 355 } 356 357 uLong DxaEncoder::m13encode(byte *frame, byte *outbuf) { 358 359 byte *codeB = _codeBuf; 360 byte *dataB = _dataBuf; 361 byte *motB = _motBuf; 362 byte *maskB = _maskBuf; 363 309 364 byte *outb = outbuf; 310 365 byte color; 311 366 int mx, my; 312 unsigned short diffMap; 313 int diffCount; 314 byte diffPix[BLOCKW*BLOCKH]; 367 DiffStruct diff; 315 368 316 for (int by = 0; by < _height; by += BLOCKH) { 369 memset(_codeBuf, 0, _width * _height / 16); 370 memset(_dataBuf, 0, _width * _height); 371 memset(_motBuf, 0, _width * _height); 372 memset(_maskBuf, 0, _width * _height); 373 374 for (int by = 0; by < _workheight; by += BLOCKH) { 317 375 for (int bx = 0; bx < _width; bx += BLOCKW) { 318 if (m12blocksAreEqual(frame, bx, by, bx, by)) {319 *outb++ = 0;320 continue;321 }322 376 323 if (m12blockIsSolidColor(frame, bx, by, color)) { 324 *outb++ = 2; 325 *outb++ = color; 377 if (m13blocksAreEqual(frame, bx, by, bx, by, BLOCKW, BLOCKH)) { 378 *codeB++ = 0; 326 379 continue; 327 380 } 328 381 329 if (m12motionVector(frame, bx, by, mx, my)) { 330 byte mbyte = 0; 331 if (mx < 0) mbyte |= 0x80; 332 mbyte |= (abs(mx) & 7) << 4; 333 if (my < 0) mbyte |= 0x08; 334 mbyte |= abs(my) & 7; 335 *outb++ = 4; 336 *outb++ = mbyte; 382 if (m13blockIsSolidColor(frame, bx, by, BLOCKW, BLOCKH, color)) { 383 *codeB++ = 2; 384 *dataB++ = color; 337 385 continue; 338 386 } 339 387 340 m12blockDelta(frame, bx, by, diffMap, diffCount, diffPix); 388 if (m13motionVector(frame, bx, by, BLOCKW, BLOCKH, mx, my)) { 389 /* motion vector */ 390 byte motionByte = 0; 391 if (mx < 0) motionByte |= 0x80; 392 motionByte |= (abs(mx) & 7) << 4; 393 if (my < 0) motionByte |= 0x08; 394 motionByte |= abs(my) & 7; 395 *codeB++ = 4; 396 *motB++ = motionByte; 397 continue; 398 } 341 399 342 if (diffCount >= 14) { 343 // in this case we store all 16 pixels 344 *outb++ = 3; 345 byte *b2 = (byte*)frame + bx + by * _width; 346 for (int yc = 0; yc < BLOCKH; yc++) { 347 memcpy(outb, b2, BLOCKW); 348 b2 += _width; 349 outb += BLOCKW; 350 } 351 continue; 352 } else { 353 static const struct { uint16 mask; uint8 sh1, sh2; } maskTbl[6] = { 354 {0xFF00, 0, 0}, 355 {0x0FF0, 8, 0}, 356 {0x00FF, 8, 8}, 357 {0x0F0F, 8, 4}, 358 {0xF0F0, 4, 0}, 359 {0xF00F, 4, 4} 360 }; 400 byte subMask = 0; 401 byte subMot[4], subData[16]; 402 int subMotSize = 0, subDataSize = 0; 361 403 362 bool smallMask = false; 404 { 363 405 364 // here we check if the difference bitmap can be stored in only one byte 365 for (int m = 0; m < 6; m++) { 366 if ((diffMap & maskTbl[m].mask) == 0) { 367 smallMask = true; 368 *outb++ = 10 + m; 369 *outb++ = ((diffMap >> maskTbl[m].sh1) & 0xF0) | ((diffMap >> maskTbl[m].sh2) & 0x0F); 370 break; 371 } 372 } 406 static const int subX[4] = {0, 2, 0, 2}; 407 static const int subY[4] = {0, 0, 2, 2}; 373 408 374 if (!smallMask) { 375 *outb++ = 1; 376 *(unsigned short*)outb = diffMap; 377 outb += 2; 378 } 409 /* 0: skip 410 1: solid color (+ data byte) 411 2: motion vector (+ mot byte) 412 3: raw block (+ 4 data bytes) 413 */ 379 414 380 memcpy(outb, diffPix, diffCount); 381 outb += diffCount; 382 continue; 383 } 415 for (int subBlock = 0; subBlock < 4; subBlock++) { 416 417 int sx = bx + subX[subBlock], sy = by + subY[subBlock]; 418 byte scolor; 419 int smx, smy; 420 421 if (m13blocksAreEqual(frame, sx, sy, sx, sy, BLOCKW/2, BLOCKH/2)) { 422 subMask = (subMask << 2) | 0; 423 continue; 424 } 425 426 if (m13blockIsSolidColor(frame, sx, sy, BLOCKW/2, BLOCKH/2, scolor)) { 427 subData[subDataSize++] = scolor; 428 subMask = (subMask << 2) | 1; 429 continue; 430 } 431 432 if (m13motionVector(frame, sx, sy, BLOCKW/2, BLOCKH/2, smx, smy)) { 433 byte motionByte = 0; 434 if (smx < 0) motionByte |= 0x80; 435 motionByte |= (abs(smx) & 7) << 4; 436 if (smy < 0) motionByte |= 0x08; 437 motionByte |= abs(smy) & 7; 438 subMot[subMotSize++] = motionByte; 439 subMask = (subMask << 2) | 2; 440 continue; 441 } 442 443 byte *b2 = (byte*)frame + sx + sy * _width; 444 for (int yc = 0; yc < BLOCKH/2; yc++) { 445 memcpy(&subData[subDataSize], b2, BLOCKW/2); 446 subDataSize += BLOCKW/2; 447 b2 += _width; 448 } 449 450 subMask = (subMask << 2) | 3; 451 452 } 453 454 } 455 456 int blockSize = 0; 457 458 m13blockDelta(frame, bx, by, bx, by, diff); 459 460 byte block[16]; 461 grabBlock(frame, bx, by, BLOCKW, BLOCKW, block); 462 463 unsigned long code; 464 int codeSize; 465 byte pixels[16]; 466 int count = m13countColors(block, pixels, code, codeSize); 467 468 int countColorsSize = 1000; 469 if (count == 2) 470 countColorsSize = 4; // 2 bytes mask, 2 pixels 471 else if (count <= 4) 472 countColorsSize = 4 + count; // 4 bytes mask, count pixels 473 474 if (countColorsSize < diff.count + 2) { 475 blockSize = countColorsSize; 476 } else { 477 if (diff.count <= 12) { 478 blockSize = 2 + diff.count; 479 } else { 480 blockSize = 16; 481 } 482 } 483 484 if (1 + subMotSize + subDataSize < blockSize) { 485 /* store subblocks */ 486 *codeB++ = 8; 487 *maskB++ = subMask; 488 memcpy(dataB, subData, subDataSize); 489 dataB += subDataSize; 490 memcpy(motB, subMot, subMotSize); 491 motB += subMotSize; 492 } else { 493 /* store full block */ 494 if (countColorsSize < diff.count + 2) { 495 /* write the pixel values */ 496 *codeB++ = 30 + count; 497 memcpy(dataB, pixels, count); 498 dataB += count; 499 memcpy(maskB, &code, codeSize); 500 maskB += codeSize; 501 } else { 502 if (diff.count <= 12) { 503 /* difference map */ 504 *codeB++ = 1; 505 *(unsigned short*)maskB = diff.map; 506 maskB += 2; 507 memcpy(dataB, diff.pixels, diff.count); 508 dataB += diff.count; 509 } else { 510 /* write the whole block */ 511 *codeB++ = 3; 512 memcpy(dataB, block, 16); 513 dataB += 16; 514 } 515 } 516 } 517 384 518 } 385 519 } 386 520 521 outb = outbuf; 522 523 int size; 524 525 size = dataB - _dataBuf; 526 memcpy(outb, &size, 4); 527 outb += 4; 528 size = motB - _motBuf; 529 memcpy(outb, &size, 4); 530 outb += 4; 531 size = maskB - _maskBuf; 532 memcpy(outb, &size, 4); 533 outb += 4; 534 535 /* this size is always constant throughout a DXA */ 536 memcpy(outb, _codeBuf, codeB - _codeBuf); 537 outb += codeB - _codeBuf; 538 539 memcpy(outb, _dataBuf, dataB - _dataBuf); 540 outb += dataB - _dataBuf; 541 542 memcpy(outb, _motBuf, motB - _motBuf); 543 outb += motB - _motBuf; 544 545 memcpy(outb, _maskBuf, maskB - _maskBuf); 546 outb += maskB - _maskBuf; 547 387 548 return outb - outbuf; 388 549 } 389 550 … … 469 630 return 0; 470 631 } 471 632 472 void readVideoInfo(char *filename, int &width, int &height, int &framerate, int &frames) { 633 void readVideoInfo(char *filename, int &width, int &height, int &framerate, int &frames, 634 ScaleMode &scaleMode) { 635 473 636 FILE *smk = fopen(filename, "rb"); 474 637 if (!smk) { 475 638 printf("readVideoInfo: Can't open file: %s\n", filename); 476 639 exit(-1); 477 640 } 478 641 642 scaleMode = S_NONE; 643 479 644 char buf[4]; 480 645 fread(buf, 1, 4, smk); 481 646 if (!memcmp(buf, "BIK", 3)) { … … 503 668 // If the Y-interlaced or Y-doubled flag is set, the RAD Video Tools 504 669 // will have scaled the frames to twice their original height. 505 670 506 if ((flags & 0x02) || (flags & 0x04)) 507 height *= 2; 671 if (flags & 0x02) 672 scaleMode = S_INTERLACED; 673 else if (flags & 0x04) 674 scaleMode = S_DOUBLE; 675 676 if (scaleMode != S_NONE) 677 height *= 2; 678 508 679 } else { 509 680 error("readVideoInfo: Unknown type"); 510 681 } … … 577 748 578 749 char strbuf[512]; 579 750 int width, height, framerate, frames; 751 ScaleMode scaleMode; 580 752 581 753 /* compression mode */ 582 754 gCompMode = kMP3Mode; … … 634 806 } 635 807 636 808 // read some data from the Bink or Smacker file. 637 readVideoInfo(filename, width, height, framerate, frames );809 readVideoInfo(filename, width, height, framerate, frames, scaleMode); 638 810 639 811 printf("Width = %d, Height = %d, Framerate = %d, Frames = %d\n", 640 812 width, height, framerate, frames); 641 813 642 814 // create the encoder object 643 815 sprintf(strbuf, "%s.dxa", prefix); 644 DxaEncoder dxe(strbuf, width, height, framerate );816 DxaEncoder dxe(strbuf, width, height, framerate, scaleMode); 645 817 646 818 // No sound block 647 819 dxe.writeNULL(); … … 671 843 } 672 844 673 845 if (!r) { 674 dxe.writeFrame(image, palette); 846 if (scaleMode != S_NONE) { 847 byte *unscaledImage = new byte[width * height / 2]; 848 for (int y = 0; y < height; y += 2) 849 memcpy(&unscaledImage[(width*y)/2], &image[width*y], width); 850 dxe.writeFrame(unscaledImage, palette); 851 delete[] unscaledImage; 852 } else { 853 dxe.writeFrame(image, palette); 854 } 675 855 } 676 856 677 857 if (image) delete[] image; … … 692 872 693 873 return 0; 694 874 } 695 696