1 /*===========================================================================*
2 * frame.c *
3 * *
4 * basic frame procedures *
5 * *
6 * EXPORTED PROCEDURES: *
7 * Frame_Init *
8 * Frame_Exit *
9 * Frame_New *
10 * Frame_Free *
11 * Frame_AllocBlocks *
12 * Frame_AllocYCC *
13 * Frame_AllocDecoded *
14 * Frame_AllocHalf *
15 * Frame_Resize *
16 * *
17 *===========================================================================*/
18
19 /*
20 * Copyright (c) 1995 The Regents of the University of California.
21 * All rights reserved.
22 *
23 * Permission to use, copy, modify, and distribute this software and its
24 * documentation for any purpose, without fee, and without written agreement is
25 * hereby granted, provided that the above copyright notice and the following
26 * two paragraphs appear in all copies of this software.
27 *
28 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
29 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
30 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
31 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
34 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
35 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
36 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
37 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
38 */
39
40
41 #include "mallocvar.h"
42
43 #include "all.h"
44 #include "mtypes.h"
45 #include "frames.h"
46 #include "frame.h"
47 #include "fsize.h"
48 #include "dct.h"
49
50 /*===========*
51 * CONSTANTS *
52 *===========*/
53
54 /* The maximum number of B-Frames allowed between reference frames. */
55 #define B_FRAME_RUN 16
56
57 /*==================*
58 * GLOBAL VARIABLES *
59 *==================*/
60
61 static MpegFrame * frameMemory[B_FRAME_RUN+2];
62 static unsigned int numOfFrames;
63
64
65 /*====================================================
66 * Resize_Array_Width
67 *
68 * This function will resize any array width up
69 * or down in size. The algorithm is based on the
70 * least common multiple approach more commonly
71 * used in audio frequency adjustments.
72 *=====================================================*/
73 static void
Resize_Array_Width(uint8 ** const inarray,int const in_x,int const in_y,uint8 ** const outarray,int const out_x)74 Resize_Array_Width(uint8 ** const inarray,
75 int const in_x,
76 int const in_y,
77 uint8 ** const outarray,
78 int const out_x) {
79
80 unsigned int i;
81 int in_total;
82 int out_total;
83 uint8 *inptr;
84 uint8 *outptr;
85 #ifdef DOING_INTERPOLATION
86 uint8 pointA,pointB;
87 double slope,diff;
88 #endif
89
90 for (i = 0; i < in_y; ++i) { /* For each row */
91 unsigned int j;
92 inptr = &inarray[i][0];
93 outptr = &outarray[i][0];
94 in_total = 0;
95 out_total = 0;
96 for (j=0; j < out_x; ++j) { /* For each output value */
97 if (in_total == out_total) {
98 *outptr = *inptr;
99 outptr++;
100 out_total=out_total+in_x;
101 while(in_total < out_total){
102 in_total = in_total + out_x;
103 ++inptr;
104 }
105 if (in_total > out_total) {
106 in_total = in_total - out_x;
107 --inptr;
108 }
109 } else {
110 #ifdef DOING_INTERPOLATION
111 pointA = *inptr;
112 #endif
113 ++inptr;
114 #ifdef DOING_INTERPOLATION
115 pointB = *inptr;
116 #endif
117 --inptr;
118 #ifdef DOING_INTERPOLATION
119 /*Interpolative solution */
120 slope = ((double)(pointB -pointA))/((double)(out_x));
121 diff = (((double)(out_total - in_total)));
122 if (diff < (out_x/2)){
123 *outptr = (pointA + (uint8)(slope*diff));
124 } else {
125 *outptr = (pointB -
126 (uint8)(slope*(((float)(out_x)) - diff)));
127 }
128 #endif
129 /* Non-Interpolative solution */
130 *outptr = *inptr;
131
132 ++outptr;
133 out_total = out_total + in_x;
134 while(in_total < out_total) {
135 in_total = in_total + out_x;
136 ++inptr;
137 }
138 if (in_total > out_total) {
139 in_total = in_total - out_x;
140 --inptr;
141 }
142 } /* end if */
143 } /* end for each output value */
144 } /* end for each row */
145 } /* end main */
146
147
148
149 /*==============================
150 * Resize_Array_Height
151 *
152 * Resize any array height larger or smaller.
153 * Same as Resize_array_Width except pointer
154 * manipulation must change.
155 *===============================*/
156 static void
Resize_Array_Height(uint8 ** const inarray,int const in_x,int const in_y,uint8 ** const outarray,int const out_y)157 Resize_Array_Height(uint8 ** const inarray,
158 int const in_x,
159 int const in_y,
160 uint8 ** const outarray,
161 int const out_y) {
162
163 unsigned int i;
164
165 for(i=0; i < in_x; ++i){ /* for each column */
166 int in_total;
167 int out_total;
168 #ifdef DOING_INTERPOLATION
169 uint8 pointA, pointB;
170 double slope, diff;
171 #endif
172 unsigned int j;
173 int k;
174
175 in_total = 0;
176 out_total = 0;
177 k = 0;
178 for(j=0; j < out_y; ++j){ /* for each output value */
179 if (in_total == out_total) {
180 outarray[j][i] = inarray[k][i];
181 out_total=out_total+in_y;
182 while(in_total < out_total){
183 in_total = in_total + out_y;
184 ++k;
185 }
186 if (in_total > out_total) {
187 in_total = in_total - out_y;
188 --k;
189 }
190 } else {
191 #ifdef DOING_INTERPOLATION
192 pointA = inarray[k][i];
193 if (k != (in_y - 1)) {
194 pointB = inarray[k+1][i];
195 } else
196 pointB = pointA;
197 /* Interpolative case */
198 slope = ((double)(pointB -pointA))/(double)(out_y);
199 diff = (double)(out_total - in_total);
200 outarray[j][i] = (inarray[k][i] + (uint8)(slope*diff));
201 #endif
202 /* Non-Interpolative case */
203 outarray[j][i] = inarray[k][i];
204 out_total = out_total + in_y;
205 while (in_total < out_total) {
206 in_total = in_total + out_y;
207 ++k;
208 }
209 if (in_total > out_total){
210 in_total = in_total - out_y;
211 --k;
212 }
213 }
214 }
215 }
216 }
217
218
219
220 /*========================================================
221 * Resize_Width
222 *======================================================*/
223 static void
Resize_Width(MpegFrame * const omfrw,MpegFrame * const mfrw,int const in_x,int const in_y,int const out_x)224 Resize_Width(MpegFrame * const omfrw,
225 MpegFrame * const mfrw,
226 int const in_x,
227 int const in_y,
228 int const out_x) {
229
230 int y;
231
232 omfrw->orig_y = NULL;
233 Fsize_x = out_x;
234
235 /* Allocate new frame memory */
236 MALLOCARRAY(omfrw->orig_y, Fsize_y);
237 ERRCHK(omfrw->orig_y, "malloc");
238 for (y = 0; y < Fsize_y; ++y) {
239 MALLOCARRAY(omfrw->orig_y[y], out_x);
240 ERRCHK(omfrw->orig_y[y], "malloc");
241 }
242
243 MALLOCARRAY(omfrw->orig_cr, Fsize_y / 2);
244 ERRCHK(omfrw->orig_cr, "malloc");
245 for (y = 0; y < Fsize_y / 2; ++y) {
246 MALLOCARRAY(omfrw->orig_cr[y], out_x / 2);
247 ERRCHK(omfrw->orig_cr[y], "malloc");
248 }
249
250 MALLOCARRAY(omfrw->orig_cb, Fsize_y / 2);
251 ERRCHK(omfrw->orig_cb, "malloc");
252 for (y = 0; y < Fsize_y / 2; ++y) {
253 MALLOCARRAY(omfrw->orig_cb[y], out_x / 2);
254 ERRCHK(omfrw->orig_cb[y], "malloc");
255 }
256
257 if (referenceFrame == ORIGINAL_FRAME) {
258 omfrw->ref_y = omfrw->orig_y;
259 omfrw->ref_cr = omfrw->orig_cr;
260 omfrw->ref_cb = omfrw->orig_cb;
261 }
262
263 /* resize each component array separately */
264 Resize_Array_Width(mfrw->orig_y, in_x, in_y, omfrw->orig_y, out_x);
265 Resize_Array_Width(mfrw->orig_cr, (in_x/2), (in_y/2), omfrw->orig_cr,
266 (out_x/2));
267 Resize_Array_Width(mfrw->orig_cb, (in_x/2), (in_y/2), omfrw->orig_cb,
268 (out_x/2));
269
270 /* Free old frame memory */
271 if (mfrw->orig_y) {
272 unsigned int i;
273 for (i = 0; i < in_y; ++i) {
274 free(mfrw->orig_y[i]);
275 }
276 free(mfrw->orig_y);
277
278 for (i = 0; i < in_y / 2; ++i) {
279 free(mfrw->orig_cr[i]);
280 }
281 free(mfrw->orig_cr);
282
283 for (i = 0; i < in_y / 2; ++i) {
284 free(mfrw->orig_cb[i]);
285 }
286 free(mfrw->orig_cb);
287 }
288 }
289
290
291
292 /*=======================================================
293 * Resize_Height
294 *
295 * Resize Frame height up or down
296 *=======================================================*/
297 static void
Resize_Height(MpegFrame * const omfrh,MpegFrame * const mfrh,int const in_x,int const in_y,int const out_y)298 Resize_Height(MpegFrame * const omfrh,
299 MpegFrame * const mfrh,
300 int const in_x,
301 int const in_y,
302 int const out_y) {
303
304 unsigned int y;
305
306 Fsize_y = out_y;
307
308 /* Allocate new frame memory */
309 MALLOCARRAY(omfrh->orig_y, out_y);
310 ERRCHK(omfrh->orig_y, "malloc");
311 for (y = 0; y < out_y; ++y) {
312 MALLOCARRAY(omfrh->orig_y[y], Fsize_x);
313 ERRCHK(omfrh->orig_y[y], "malloc");
314 }
315
316 MALLOCARRAY(omfrh->orig_cr, out_y / 2);
317 ERRCHK(omfrh->orig_cr, "malloc");
318 for (y = 0; y < out_y / 2; ++y) {
319 MALLOCARRAY(omfrh->orig_cr[y], Fsize_x / 2);
320 ERRCHK(omfrh->orig_cr[y], "malloc");
321 }
322
323 MALLOCARRAY(omfrh->orig_cb, out_y / 2);
324 ERRCHK(omfrh->orig_cb, "malloc");
325 for (y = 0; y < out_y / 2; ++y) {
326 MALLOCARRAY(omfrh->orig_cb[y], Fsize_x / 2);
327 ERRCHK(omfrh->orig_cb[y], "malloc");
328 }
329
330 if (referenceFrame == ORIGINAL_FRAME) {
331 omfrh->ref_y = omfrh->orig_y;
332 omfrh->ref_cr = omfrh->orig_cr;
333 omfrh->ref_cb = omfrh->orig_cb;
334 }
335
336 /* resize component arrays separately */
337 Resize_Array_Height(mfrh->orig_y, in_x, in_y, omfrh->orig_y, out_y);
338 Resize_Array_Height(mfrh->orig_cr, (in_x/2), (in_y/2), omfrh->orig_cr,
339 (out_y/2));
340 Resize_Array_Height(mfrh->orig_cb, (in_x/2), (in_y/2), omfrh->orig_cb,
341 (out_y/2));
342
343 /* Free old frame memory */
344 if (mfrh->orig_y) {
345 unsigned int i;
346 for (i = 0; i < in_y; ++i) {
347 free(mfrh->orig_y[i]);
348 }
349 free(mfrh->orig_y);
350
351 for (i = 0; i < in_y / 2; ++i) {
352 free(mfrh->orig_cr[i]);
353 }
354 free(mfrh->orig_cr);
355
356 for (i = 0; i < in_y / 2; ++i) {
357 free(mfrh->orig_cb[i]);
358 }
359 free(mfrh->orig_cb);
360 }
361 }
362
363
364
365 /*===========================================================================*
366 *
367 * Frame_Init
368 *
369 * initializes the memory associated with all frames ever
370 * If the input is not coming in from stdin, only 3 frames are needed ;
371 * else, the program must create frames equal to the greatest distance
372 * between two reference frames to hold the B frames while it is parsing
373 * the input from stdin.
374 *
375 * RETURNS: nothing
376 *
377 * SIDE EFFECTS: frameMemory, numOfFrames
378 *
379 *===========================================================================*/
380 void
Frame_Init(unsigned int const numOfFramesRequested)381 Frame_Init(unsigned int const numOfFramesRequested) {
382 int idx;
383
384 numOfFrames = numOfFramesRequested;
385
386 for (idx = 0; idx < numOfFrames; ++idx) {
387 MALLOCVAR(frameMemory[idx]);
388 frameMemory[idx]->inUse = FALSE;
389 frameMemory[idx]->orig_y = NULL;
390 frameMemory[idx]->y_blocks = NULL;
391 frameMemory[idx]->decoded_y = NULL;
392 frameMemory[idx]->halfX = NULL;
393 frameMemory[idx]->next = NULL;
394 }
395 }
396
397
398 /*===========================================================================*
399 *
400 * FreeFrame
401 *
402 * frees the memory associated with the given frame
403 *
404 * RETURNS: nothing
405 *
406 * SIDE EFFECTS: none
407 *
408 *===========================================================================*/
409 static void
FreeFrame(MpegFrame * const frameP)410 FreeFrame(MpegFrame * const frameP) {
411
412 if (frameP) {
413 if (frameP->orig_y) {
414 unsigned int i;
415 for (i = 0; i < Fsize_y; ++i)
416 free(frameP->orig_y[i]);
417 free(frameP->orig_y);
418
419 for (i = 0; i < (Fsize_y / 2); ++i)
420 free(frameP->orig_cr[i]);
421 free(frameP->orig_cr);
422
423 for (i = 0; i < (Fsize_y / 2); ++i)
424 free(frameP->orig_cb[i]);
425 free(frameP->orig_cb);
426 }
427 if (frameP->decoded_y) {
428 unsigned int i;
429 for (i = 0; i < Fsize_y; ++i)
430 free(frameP->decoded_y[i]);
431 free(frameP->decoded_y);
432
433 for (i = 0; i < (Fsize_y / 2); ++i)
434 free(frameP->decoded_cr[i]);
435 free(frameP->decoded_cr);
436
437 for (i = 0; i < (Fsize_y / 2); ++i)
438 free(frameP->decoded_cb[i]);
439 free(frameP->decoded_cb);
440 }
441
442 if (frameP->y_blocks) {
443 unsigned int i;
444 for (i = 0; i < Fsize_y / DCTSIZE; ++i)
445 free(frameP->y_blocks[i]);
446 free(frameP->y_blocks);
447
448 for (i = 0; i < Fsize_y / (2 * DCTSIZE); ++i)
449 free(frameP->cr_blocks[i]);
450 free(frameP->cr_blocks);
451
452 for (i = 0; i < Fsize_y / (2 * DCTSIZE); ++i)
453 free(frameP->cb_blocks[i]);
454 free(frameP->cb_blocks);
455 }
456 if (frameP->halfX) {
457 unsigned int i;
458 for ( i = 0; i < Fsize_y; ++i )
459 free(frameP->halfX[i]);
460 free(frameP->halfX);
461
462 for (i = 0; i < Fsize_y-1; ++i)
463 free(frameP->halfY[i]);
464 free(frameP->halfY);
465
466 for (i = 0; i < Fsize_y-1; ++i)
467 free(frameP->halfBoth[i]);
468 free(frameP->halfBoth);
469 }
470 free(frameP);
471 }
472 }
473
474
475
476 /*===========================================================================*
477 *
478 * Frame_Exit
479 *
480 * frees the memory associated with frames
481 *
482 * RETURNS: nothing
483 *
484 * SIDE EFFECTS: frameMemory
485 *
486 *===========================================================================*/
487 void
Frame_Exit(void)488 Frame_Exit(void) {
489
490 int idx;
491
492 for (idx = 0; idx < numOfFrames; ++idx) {
493 FreeFrame(frameMemory[idx]);
494 }
495 }
496
497
498 /*===========================================================================*
499 *
500 * Frame_Free
501 *
502 * frees the given frame -- allows it to be re-used
503 *
504 * RETURNS: nothing
505 *
506 * SIDE EFFECTS: none
507 *
508 *===========================================================================*/
509 void
Frame_Free(MpegFrame * const frameP)510 Frame_Free(MpegFrame * const frameP) {
511 frameP->inUse = FALSE;
512 }
513
514
515
516 /*===========================================================================*
517 *
518 * GetUnusedFrame
519 *
520 * return an unused frame
521 *
522 * RETURNS: the frame
523 *
524 * SIDE EFFECTS: none
525 *
526 *===========================================================================*/
527 static MpegFrame *
GetUnusedFrame()528 GetUnusedFrame() {
529 unsigned int idx;
530
531 for (idx = 0; idx < numOfFrames; ++idx) {
532 if (!frameMemory[idx]->inUse) {
533 frameMemory[idx]->inUse = TRUE;
534 break;
535 }
536 }
537 if (idx >= numOfFrames) {
538 fprintf(stderr, "ERROR: No unused frames!!!\n");
539 fprintf(stderr, " If you are using stdin for input, "
540 "it is likely that you have too many\n");
541 fprintf(stderr, " B-frames between two reference frames. "
542 "See the man page for help.\n");
543 exit(1);
544 }
545 return frameMemory[idx];
546 }
547
548
549
550 /*===========================================================================*
551 *
552 * ResetFrame
553 *
554 * reset a frame to the given id and type
555 *
556 * RETURNS: nothing
557 *
558 * SIDE EFFECTS: none
559 *
560 *===========================================================================*/
561 static void
ResetFrame(int const id,int const type,MpegFrame * const frame)562 ResetFrame(int const id,
563 int const type,
564 MpegFrame * const frame) {
565
566 switch (type) {
567 case 'i':
568 frame->type = TYPE_IFRAME;
569 break;
570 case 'p':
571 frame->type = TYPE_PFRAME;
572 break;
573 case 'b':
574 frame->type = TYPE_BFRAME;
575 break;
576 default:
577 fprintf(stderr, "Invalid MPEG frame type %c\n", type);
578 exit(1);
579 }
580
581 frame->id = id;
582 frame->halfComputed = FALSE;
583 frame->next = NULL;
584 }
585
586
587
588 /*===========================================================================*
589 *
590 * Frame_New
591 *
592 * finds a frame that isn't currently being used and resets it
593 *
594 * RETURNS: the frame
595 *
596 * SIDE EFFECTS: none
597 *
598 *===========================================================================*/
599 MpegFrame *
Frame_New(int const id,int const type)600 Frame_New(int const id,
601 int const type) {
602
603 MpegFrame *frame;
604
605 frame = GetUnusedFrame();
606 ResetFrame(id, type, frame);
607
608 return frame;
609 }
610
611
612
613 /*===========================================================================*
614 *
615 * Frame_AllocBlocks
616 *
617 * allocate memory for blocks for the given frame, if required
618 *
619 * RETURNS: nothing
620 *
621 * SIDE EFFECTS: none
622 *
623 *===========================================================================*/
624 void
Frame_AllocBlocks(MpegFrame * const frameP)625 Frame_AllocBlocks(MpegFrame * const frameP) {
626
627 if (frameP->y_blocks != NULL) {
628 /* already allocated */
629 } else {
630 int const dctx = Fsize_x / DCTSIZE;
631 int const dcty = Fsize_y / DCTSIZE;
632
633 unsigned int i;
634
635 MALLOCARRAY(frameP->y_blocks, dcty);
636 ERRCHK(frameP->y_blocks, "malloc");
637 for (i = 0; i < dcty; ++i) {
638 MALLOCARRAY(frameP->y_blocks[i], dctx);
639 ERRCHK(frameP->y_blocks[i], "malloc");
640 }
641
642 MALLOCARRAY(frameP->cr_blocks, dcty / 2);
643 ERRCHK(frameP->cr_blocks, "malloc");
644 MALLOCARRAY(frameP->cb_blocks, dcty / 2);
645 ERRCHK(frameP->cb_blocks, "malloc");
646 for (i = 0; i < (dcty / 2); ++i) {
647 MALLOCARRAY(frameP->cr_blocks[i], dctx / 2);
648 ERRCHK(frameP->cr_blocks[i], "malloc");
649 MALLOCARRAY(frameP->cb_blocks[i], dctx / 2);
650 ERRCHK(frameP->cb_blocks[i], "malloc");
651 }
652 }
653 }
654
655
656
657 /*===========================================================================*
658 *
659 * Frame_AllocYCC
660 *
661 * allocate memory for YCC info for the given frame, if required
662 *
663 * RETURNS: nothing
664 *
665 * SIDE EFFECTS: none
666 *
667 *===========================================================================*/
668 void
Frame_AllocYCC(MpegFrame * const frameP)669 Frame_AllocYCC(MpegFrame * const frameP) {
670
671 if (frameP->orig_y != NULL) {
672 /* already allocated */
673 } else {
674 unsigned int y;
675
676 DBG_PRINT(("ycc_calc:\n"));
677 /*
678 * first, allocate tons of memory
679 */
680 MALLOCARRAY(frameP->orig_y, Fsize_y);
681 ERRCHK(frameP->orig_y, "malloc");
682 for (y = 0; y < Fsize_y; ++y) {
683 MALLOCARRAY(frameP->orig_y[y], Fsize_x);
684 ERRCHK(frameP->orig_y[y], "malloc");
685 }
686
687 MALLOCARRAY(frameP->orig_cr, Fsize_y / 2);
688 ERRCHK(frameP->orig_cr, "malloc");
689 for (y = 0; y < (Fsize_y / 2); ++y) {
690 MALLOCARRAY(frameP->orig_cr[y], Fsize_x / 2);
691 ERRCHK(frameP->orig_cr[y], "malloc");
692 }
693
694 MALLOCARRAY(frameP->orig_cb, Fsize_y / 2);
695 ERRCHK(frameP->orig_cb, "malloc");
696 for (y = 0; y < (Fsize_y / 2); ++y) {
697 MALLOCARRAY(frameP->orig_cb[y], Fsize_x / 2);
698 ERRCHK(frameP->orig_cb[y], "malloc");
699 }
700
701 if (referenceFrame == ORIGINAL_FRAME) {
702 frameP->ref_y = frameP->orig_y;
703 frameP->ref_cr = frameP->orig_cr;
704 frameP->ref_cb = frameP->orig_cb;
705 }
706 }
707 }
708
709
710
711 /*===========================================================================*
712 *
713 * Frame_AllocHalf
714 *
715 * allocate memory for half-pixel values for the given frame, if required
716 *
717 * RETURNS: nothing
718 *
719 * SIDE EFFECTS: none
720 *
721 *===========================================================================*/
722 void
Frame_AllocHalf(MpegFrame * const frameP)723 Frame_AllocHalf(MpegFrame * const frameP) {
724
725 if (frameP->halfX != NULL) {
726 } else {
727 unsigned int y;
728
729 MALLOCARRAY(frameP->halfX, Fsize_y);
730 ERRCHK(frameP->halfX, "malloc");
731 for (y = 0; y < Fsize_y; ++y) {
732 MALLOCARRAY(frameP->halfX[y], Fsize_x - 1);
733 ERRCHK(frameP->halfX[y], "malloc");
734 }
735 MALLOCARRAY(frameP->halfY, Fsize_y - 1);
736 ERRCHK(frameP->halfY, "malloc");
737 for (y = 0; y < Fsize_y - 1; ++y) {
738 MALLOCARRAY(frameP->halfY[y], Fsize_x);
739 ERRCHK(frameP->halfY[y], "malloc");
740 }
741 MALLOCARRAY(frameP->halfBoth, Fsize_y - 1);
742 ERRCHK(frameP->halfBoth, "malloc");
743 for (y = 0; y < Fsize_y - 1; ++y) {
744 MALLOCARRAY(frameP->halfBoth[y], Fsize_x - 1);
745 ERRCHK(frameP->halfBoth[y], "malloc");
746 }
747 }
748 }
749
750
751
752 /*===========================================================================*
753 *
754 * Frame_AllocDecoded
755 *
756 * allocate memory for decoded frame for the given frame, if required
757 * if makeReference == TRUE, then makes it reference frame
758 *
759 * RETURNS: nothing
760 *
761 * SIDE EFFECTS: none
762 *
763 *===========================================================================*/
764 void
Frame_AllocDecoded(MpegFrame * const frameP,bool const makeReference)765 Frame_AllocDecoded(MpegFrame * const frameP,
766 bool const makeReference) {
767
768 if (frameP->decoded_y != NULL) {
769 /* already allocated */
770 } else {
771 unsigned int y;
772
773 /* allocate memory for decoded image */
774 /* can probably reuse original image memory, but may decide to use
775 it for some reason, so do it this way at least for now -- more
776 flexible
777 */
778 MALLOCARRAY(frameP->decoded_y, Fsize_y);
779 ERRCHK(frameP->decoded_y, "malloc");
780 for (y = 0; y < Fsize_y; ++y) {
781 MALLOCARRAY(frameP->decoded_y[y], Fsize_x);
782 ERRCHK(frameP->decoded_y[y], "malloc");
783 }
784
785 MALLOCARRAY(frameP->decoded_cr, Fsize_y / 2);
786 ERRCHK(frameP->decoded_cr, "malloc");
787 for (y = 0; y < (Fsize_y / 2); ++y) {
788 MALLOCARRAY(frameP->decoded_cr[y], Fsize_x / 2);
789 ERRCHK(frameP->decoded_cr[y], "malloc");
790 }
791
792 MALLOCARRAY(frameP->decoded_cb, Fsize_y / 2);
793 ERRCHK(frameP->decoded_cb, "malloc");
794 for (y = 0; y < (Fsize_y / 2); ++y) {
795 MALLOCARRAY(frameP->decoded_cb[y], Fsize_x / 2);
796 ERRCHK(frameP->decoded_cb[y], "malloc");
797 }
798
799 if (makeReference) {
800 frameP->ref_y = frameP->decoded_y;
801 frameP->ref_cr = frameP->decoded_cr;
802 frameP->ref_cb = frameP->decoded_cb;
803 }
804 }
805 }
806
807
808
809 /*===============================================================
810 *
811 * Frame_Resize by James Boucher
812 * Boston University Multimedia Communications Lab
813 *
814 * This function takes the mf input frame, read in READFrame(),
815 * and resizes all the input component arrays to the output
816 * dimensions specified in the parameter file as OUT_SIZE.
817 * The new frame is returned with the omf pointer. As well,
818 * the values of Fsize_x and Fsize_y are adjusted.
819 ***************************************************************/
820 void
Frame_Resize(MpegFrame * const omf,MpegFrame * const mf,int const insize_x,int const insize_y,int const outsize_x,int const outsize_y)821 Frame_Resize(MpegFrame * const omf,
822 MpegFrame * const mf,
823 int const insize_x,
824 int const insize_y,
825 int const outsize_x,
826 int const outsize_y) {
827
828 MpegFrame * frameAP; /* intermediate frame */
829
830 MALLOCVAR_NOFAIL(frameAP);
831
832 if (insize_x != outsize_x && insize_y != outsize_y) {
833 Resize_Width(frameAP, mf, insize_x, insize_y, outsize_x);
834 Resize_Height(omf, frameAP, outsize_x, insize_y, outsize_y);
835 } else
836 if (insize_x ==outsize_x && insize_y != outsize_y) {
837 Resize_Height(omf, mf, insize_x, insize_y, outsize_y);
838 } else
839 if (insize_x !=outsize_x && insize_y == outsize_y) {
840 Resize_Width(omf, mf, insize_x, insize_y, outsize_x);
841 } else
842 exit(1);
843
844 free(frameAP);
845 free(mf);
846 }
847