Stefan Schuermans commited on 2014-05-10 14:17:11
Showing 5 changed files, with 178 additions and 28 deletions.
| ... | ... |
@@ -219,7 +219,7 @@ int main(int argCnt, char **args) |
| 219 | 219 |
stBlinkenMovie *pMovie; |
| 220 | 220 |
int i; |
| 221 | 221 |
char *str; |
| 222 |
- unsigned int height, width, channels, colors, times; |
|
| 222 |
+ unsigned int height, width, channels, colors, times, top, left; |
|
| 223 | 223 |
int mode; |
| 224 | 224 |
|
| 225 | 225 |
// print info |
| ... | ... |
@@ -253,6 +253,8 @@ int main(int argCnt, char **args) |
| 253 | 253 |
" print movie\n" |
| 254 | 254 |
" -r <width>x<height>-<channels>/<colors>\n" |
| 255 | 255 |
" resize movie\n" |
| 256 |
+ " -cr <src-x>,<src-y> <width>x<height>\n" |
|
| 257 |
+ " crop movie\n" |
|
| 256 | 258 |
" -s <width>x<height>\n" |
| 257 | 259 |
" scale movie\n" |
| 258 | 260 |
" -c <channels> [solid|rainbow]\n" |
| ... | ... |
@@ -367,7 +369,7 @@ int main(int argCnt, char **args) |
| 367 | 369 |
printf("movie looped %u times\n", times);
|
| 368 | 370 |
} |
| 369 | 371 |
} else |
| 370 |
- printf("missing movie format for \"-r\"\n");
|
|
| 372 |
+ printf("missing loop count for \"-l\"\n");
|
|
| 371 | 373 |
} |
| 372 | 374 |
// output format, frame count and duration of movie |
| 373 | 375 |
else if (strcmp(args[i], "-f") == 0) {
|
| ... | ... |
@@ -415,6 +417,32 @@ int main(int argCnt, char **args) |
| 415 | 417 |
} else |
| 416 | 418 |
printf("missing movie format for \"-r\"\n");
|
| 417 | 419 |
} |
| 420 |
+ // crop movie |
|
| 421 |
+ else if (strcmp(args[i], "-cr") == 0) {
|
|
| 422 |
+ if (i + 2 < argCnt) {
|
|
| 423 |
+ const char *topleft, *dimensions; |
|
| 424 |
+ i++; |
|
| 425 |
+ topleft = args[i]; |
|
| 426 |
+ i++; |
|
| 427 |
+ dimensions = args[i]; |
|
| 428 |
+ if (sscanf |
|
| 429 |
+ (topleft, "%u,%u", &left, &top) != 2) |
|
| 430 |
+ printf("invalid top-left position \"%s\"\n", topleft);
|
|
| 431 |
+ else if (sscanf |
|
| 432 |
+ (dimensions, "%ux%u", &width, &height) != 2) |
|
| 433 |
+ printf("invalid movie dimensions \"%s\"\n", dimensions);
|
|
| 434 |
+ else if (pMovie == NULL) |
|
| 435 |
+ printf("no movie loaded to crop\n");
|
|
| 436 |
+ else {
|
|
| 437 |
+ BlinkenMovieCrop(pMovie, top, left, height, width); |
|
| 438 |
+ printf("movie cropped to %u,%u %ux%u\n", left, top, width, height);
|
|
| 439 |
+ } |
|
| 440 |
+ } else if (i + 1 < argCnt) {
|
|
| 441 |
+ printf("missing dimensions for \"-cr\"\n");
|
|
| 442 |
+ i++; |
|
| 443 |
+ } else |
|
| 444 |
+ printf("missing top-left position for \"-cr\"\n");
|
|
| 445 |
+ } |
|
| 418 | 446 |
// scale movie |
| 419 | 447 |
else if (strcmp(args[i], "-s") == 0) {
|
| 420 | 448 |
if (i + 1 < argCnt) {
|
| ... | ... |
@@ -339,12 +339,13 @@ int BlinkenFrameCompare(stBlinkenFrame *pFrame1, stBlinkenFrame *pFrame2) |
| 339 | 339 |
return 0; |
| 340 | 340 |
} |
| 341 | 341 |
|
| 342 |
-void BlinkenFrameResize(stBlinkenFrame *pFrame, int height, int width, |
|
| 343 |
- int channels, int maxval) |
|
| 342 |
+static void BlinkenFramePadCrop(stBlinkenFrame *pFrame, int height, int width, |
|
| 343 |
+ int channels, int maxval, |
|
| 344 |
+ int emptyY, int emptyX, int skipY, int skipX) |
|
| 344 | 345 |
{
|
| 345 | 346 |
unsigned char **ppData; |
| 346 | 347 |
int y, x, c, i, j; |
| 347 |
- int emptyY, emptyX, skipY, skipX, rangeY, rangeX; |
|
| 348 |
+ int rangeY, rangeX; |
|
| 348 | 349 |
unsigned long val, div; |
| 349 | 350 |
|
| 350 | 351 |
if (pFrame == NULL) |
| ... | ... |
@@ -367,14 +368,13 @@ void BlinkenFrameResize(stBlinkenFrame *pFrame, int height, int width, |
| 367 | 368 |
if (maxval > BlinkenMaxvalMax) |
| 368 | 369 |
maxval = BlinkenMaxvalMax; |
| 369 | 370 |
|
| 370 |
- if (height == pFrame->height && |
|
| 371 |
- width == pFrame->width && |
|
| 372 |
- channels == pFrame->channels && maxval == pFrame->maxval) |
|
| 371 |
+ if (height == pFrame->height && width == pFrame->width && |
|
| 372 |
+ channels == pFrame->channels && maxval == pFrame->maxval && |
|
| 373 |
+ emptyX == 0 && emptyY == 0 && skipY == 0 && skipX == 0) |
|
| 373 | 374 |
return; |
| 374 | 375 |
|
| 375 | 376 |
// allocate new data array |
| 376 |
- ppData = |
|
| 377 |
- (unsigned char **)BlinkenMalloc2D(height, width * channels, |
|
| 377 |
+ ppData = (unsigned char **)BlinkenMalloc2D(height, width * channels, |
|
| 378 | 378 |
sizeof(unsigned char)); |
| 379 | 379 |
if (ppData == NULL) |
| 380 | 380 |
return; |
| ... | ... |
@@ -383,27 +383,27 @@ void BlinkenFrameResize(stBlinkenFrame *pFrame, int height, int width, |
| 383 | 383 |
for (c = 0; c < channels; c++, i++) |
| 384 | 384 |
ppData[y][i] = 0; |
| 385 | 385 |
|
| 386 |
- // get number of pixels to skip / to leave empty in X and Y direction |
|
| 387 |
- if (height > pFrame->height) {
|
|
| 388 |
- emptyY = (height - pFrame->height) / 2; |
|
| 389 |
- skipY = 0; |
|
| 390 |
- rangeY = pFrame->height; |
|
| 391 |
- } else {
|
|
| 386 |
+ // sanitize number of pixels to skip / to leave empty in X and Y direction |
|
| 387 |
+ if (emptyY < 0) |
|
| 392 | 388 |
emptyY = 0; |
| 393 |
- skipY = (pFrame->height - height) / 2; |
|
| 394 |
- rangeY = height; |
|
| 395 |
- } |
|
| 396 |
- if (width > pFrame->width) {
|
|
| 397 |
- emptyX = (width - pFrame->width) / 2; |
|
| 398 |
- skipX = 0; |
|
| 399 |
- rangeX = pFrame->width; |
|
| 400 |
- } else {
|
|
| 389 |
+ if (emptyY > height) |
|
| 390 |
+ emptyY = height; |
|
| 391 |
+ if (emptyX < 0) |
|
| 401 | 392 |
emptyX = 0; |
| 402 |
- skipX = (pFrame->width - width) / 2; |
|
| 403 |
- rangeX = width; |
|
| 404 |
- } |
|
| 393 |
+ if (emptyX > width) |
|
| 394 |
+ emptyX = width; |
|
| 395 |
+ if (skipY < 0) |
|
| 396 |
+ skipY = 0; |
|
| 397 |
+ if (skipY > pFrame->height) |
|
| 398 |
+ skipY = pFrame->height; |
|
| 399 |
+ if (skipX < 0) |
|
| 400 |
+ skipX = 0; |
|
| 401 |
+ if (skipX > pFrame->width) |
|
| 402 |
+ skipX = pFrame->width; |
|
| 403 |
+ rangeY = mini(height - emptyY, pFrame->height - skipY); |
|
| 404 |
+ rangeX = mini(width - emptyX, pFrame->width - skipX); |
|
| 405 | 405 |
|
| 406 |
- // resize frame with help of calculated parameters |
|
| 406 |
+ // pad/crop frame with help of calculated parameters |
|
| 407 | 407 |
for (y = 0; y < rangeY; y++) {
|
| 408 | 408 |
for (x = 0; x < rangeX; x++) {
|
| 409 | 409 |
i = (skipX + x) * pFrame->channels; |
| ... | ... |
@@ -444,6 +444,88 @@ void BlinkenFrameResize(stBlinkenFrame *pFrame, int height, int width, |
| 444 | 444 |
pFrame->ppData = ppData; |
| 445 | 445 |
} |
| 446 | 446 |
|
| 447 |
+void BlinkenFrameResize(stBlinkenFrame *pFrame, int height, int width, |
|
| 448 |
+ int channels, int maxval) |
|
| 449 |
+{
|
|
| 450 |
+ int emptyY, emptyX, skipY, skipX; |
|
| 451 |
+ |
|
| 452 |
+ if (pFrame == NULL) |
|
| 453 |
+ return; |
|
| 454 |
+ |
|
| 455 |
+ if (height < BlinkenHeightMin) |
|
| 456 |
+ height = BlinkenHeightMin; |
|
| 457 |
+ if (height > BlinkenHeightMax) |
|
| 458 |
+ height = BlinkenHeightMax; |
|
| 459 |
+ if (width < BlinkenWidthMin) |
|
| 460 |
+ width = BlinkenWidthMin; |
|
| 461 |
+ if (width > BlinkenWidthMax) |
|
| 462 |
+ width = BlinkenWidthMax; |
|
| 463 |
+ if (channels < BlinkenChannelsMin) |
|
| 464 |
+ channels = BlinkenChannelsMin; |
|
| 465 |
+ if (channels > BlinkenChannelsMax) |
|
| 466 |
+ channels = BlinkenMaxvalMax; |
|
| 467 |
+ if (maxval < BlinkenMaxvalMin) |
|
| 468 |
+ maxval = BlinkenMaxvalMin; |
|
| 469 |
+ if (maxval > BlinkenMaxvalMax) |
|
| 470 |
+ maxval = BlinkenMaxvalMax; |
|
| 471 |
+ |
|
| 472 |
+ if (height == pFrame->height && width == pFrame->width && |
|
| 473 |
+ channels == pFrame->channels && maxval == pFrame->maxval) |
|
| 474 |
+ return; |
|
| 475 |
+ |
|
| 476 |
+ // get number of pixels to skip / to leave empty in X and Y direction |
|
| 477 |
+ if (height > pFrame->height) {
|
|
| 478 |
+ emptyY = (height - pFrame->height) / 2; |
|
| 479 |
+ skipY = 0; |
|
| 480 |
+ } else {
|
|
| 481 |
+ emptyY = 0; |
|
| 482 |
+ skipY = (pFrame->height - height) / 2; |
|
| 483 |
+ } |
|
| 484 |
+ if (width > pFrame->width) {
|
|
| 485 |
+ emptyX = (width - pFrame->width) / 2; |
|
| 486 |
+ skipX = 0; |
|
| 487 |
+ } else {
|
|
| 488 |
+ emptyX = 0; |
|
| 489 |
+ skipX = (pFrame->width - width) / 2; |
|
| 490 |
+ } |
|
| 491 |
+ |
|
| 492 |
+ // resize frame with help of calculated parameters |
|
| 493 |
+ BlinkenFramePadCrop(pFrame, height, width, channels, maxval, |
|
| 494 |
+ emptyY, emptyX, skipY, skipX); |
|
| 495 |
+} |
|
| 496 |
+ |
|
| 497 |
+void BlinkenFrameCrop(stBlinkenFrame *pFrame, int top, int left, |
|
| 498 |
+ int height, int width) |
|
| 499 |
+{
|
|
| 500 |
+ if (pFrame == NULL) |
|
| 501 |
+ return; |
|
| 502 |
+ |
|
| 503 |
+ if (top < 0) |
|
| 504 |
+ top = 0; |
|
| 505 |
+ if (top > pFrame->height - BlinkenHeightMin) |
|
| 506 |
+ top = pFrame->height - BlinkenHeightMin; |
|
| 507 |
+ if (height < BlinkenHeightMin) |
|
| 508 |
+ height = BlinkenHeightMin; |
|
| 509 |
+ if (height > pFrame->height - top) |
|
| 510 |
+ height = pFrame->height - top; |
|
| 511 |
+ if (left < 0) |
|
| 512 |
+ left = 0; |
|
| 513 |
+ if (left > pFrame->width - BlinkenWidthMin) |
|
| 514 |
+ left = pFrame->width - BlinkenWidthMin; |
|
| 515 |
+ if (width < BlinkenWidthMin) |
|
| 516 |
+ width = BlinkenWidthMin; |
|
| 517 |
+ if (width > pFrame->width - left) |
|
| 518 |
+ width = pFrame->width - left; |
|
| 519 |
+ |
|
| 520 |
+ if (top == 0 && left == 0 && |
|
| 521 |
+ height == pFrame->height && width == pFrame->width) |
|
| 522 |
+ return; |
|
| 523 |
+ |
|
| 524 |
+ // crop frame with help of calculated parameters |
|
| 525 |
+ BlinkenFramePadCrop(pFrame, height, width, pFrame->channels, pFrame->maxval, |
|
| 526 |
+ 0, 0, top, left); |
|
| 527 |
+} |
|
| 528 |
+ |
|
| 447 | 529 |
void BlinkenFrameScale(stBlinkenFrame *pFrame, int height, int width) |
| 448 | 530 |
{
|
| 449 | 531 |
unsigned char **ppData; |
| ... | ... |
@@ -48,6 +48,8 @@ int BlinkenFrameCompare(stBlinkenFrame *pFrame1, stBlinkenFrame *pFrame2); |
| 48 | 48 |
|
| 49 | 49 |
void BlinkenFrameResize(stBlinkenFrame *pFrame, int height, int width, |
| 50 | 50 |
int channels, int maxval); |
| 51 |
+void BlinkenFrameCrop(stBlinkenFrame *pFrame, int top, int left, |
|
| 52 |
+ int height, int width); |
|
| 51 | 53 |
void BlinkenFrameScale(stBlinkenFrame *pFrame, int height, int width); |
| 52 | 54 |
void BlinkenFrameColorize(stBlinkenFrame *pFrame, int channels, int mode, |
| 53 | 55 |
int step); |
| ... | ... |
@@ -567,6 +567,42 @@ void BlinkenMovieResize(stBlinkenMovie *pMovie, int height, int width, |
| 567 | 567 |
BlinkenFrameResize(pMovie->ppFrames[i], height, width, channels, maxval); |
| 568 | 568 |
} |
| 569 | 569 |
|
| 570 |
+void BlinkenMovieCrop(stBlinkenMovie *pMovie, int top, int left, |
|
| 571 |
+ int height, int width) |
|
| 572 |
+{
|
|
| 573 |
+ int i; |
|
| 574 |
+ |
|
| 575 |
+ if (pMovie == NULL) |
|
| 576 |
+ return; |
|
| 577 |
+ |
|
| 578 |
+ if (top < 0) |
|
| 579 |
+ top = 0; |
|
| 580 |
+ if (top > pMovie->height - BlinkenHeightMin) |
|
| 581 |
+ top = pMovie->height - BlinkenHeightMin; |
|
| 582 |
+ if (height < BlinkenHeightMin) |
|
| 583 |
+ height = BlinkenHeightMin; |
|
| 584 |
+ if (height > pMovie->height - top) |
|
| 585 |
+ height = pMovie->height - top; |
|
| 586 |
+ if (left < 0) |
|
| 587 |
+ left = 0; |
|
| 588 |
+ if (left > pMovie->width - BlinkenWidthMin) |
|
| 589 |
+ left = pMovie->width - BlinkenWidthMin; |
|
| 590 |
+ if (width < BlinkenWidthMin) |
|
| 591 |
+ width = BlinkenWidthMin; |
|
| 592 |
+ if (width > pMovie->width - left) |
|
| 593 |
+ width = pMovie->width - left; |
|
| 594 |
+ |
|
| 595 |
+ if (top == 0 && left == 0 && |
|
| 596 |
+ height == pMovie->height && width == pMovie->width) |
|
| 597 |
+ return; |
|
| 598 |
+ |
|
| 599 |
+ pMovie->height = height; |
|
| 600 |
+ pMovie->width = width; |
|
| 601 |
+ |
|
| 602 |
+ for (i = 0; i < pMovie->frameCnt; i++) |
|
| 603 |
+ BlinkenFrameCrop(pMovie->ppFrames[i], top, left, height, width); |
|
| 604 |
+} |
|
| 605 |
+ |
|
| 570 | 606 |
void BlinkenMovieScale(stBlinkenMovie *pMovie, int height, int width) |
| 571 | 607 |
{
|
| 572 | 608 |
int i; |
| ... | ... |
@@ -63,6 +63,8 @@ void BlinkenMovieReverse(stBlinkenMovie *pMovie); |
| 63 | 63 |
|
| 64 | 64 |
void BlinkenMovieResize(stBlinkenMovie *pMovie, int height, int width, |
| 65 | 65 |
int channels, int maxval); |
| 66 |
+void BlinkenMovieCrop(stBlinkenMovie *pMovie, int top, int left, |
|
| 67 |
+ int height, int width); |
|
| 66 | 68 |
void BlinkenMovieScale(stBlinkenMovie *pMovie, int height, int width); |
| 67 | 69 |
void BlinkenMovieColorize(stBlinkenMovie *pMovie, int channels, int mode); |
| 68 | 70 |
void BlinkenMovieCopyRect(stBlinkenMovie *pDest, int destY, int destX, |
| 69 | 71 |