tps_bfshape.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:17k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*************************************************************************
  2. This software module was originally developed by 
  3. Hiroyuki Katata (katata@imgsl.mkhar.sharp.co.jp), Sharp Corporation
  4. Norio Ito (norio@imgsl.mkhar.sharp.co.jp), Sharp Corporation
  5. Shuichi Watanabe (watanabe@imgsl.mkhar.sharp.co.jp), Sharp Corporation
  6. (date: August, 1997)
  7. in the course of development of the MPEG-4 Video (ISO/IEC 14496-2). This
  8. software module is an implementation of a part of one or more MPEG-4 Video
  9. tools as specified by the MPEG-4 Video. ISO/IEC gives users of the MPEG-4
  10. Video free license to this software module or modifications thereof for use
  11. in hardware or software products claiming conformance to the MPEG-4
  12. Video. Those intending to use this software module in hardware or software
  13. products are advised that its use may infringe existing patents. The
  14. original developer of this software module and his/her company, the
  15. subsequent editors and their companies, and ISO/IEC have no liability for
  16. use of this software module or modifications thereof in an
  17. implementation. Copyright is not released for non MPEG-4 Video conforming
  18. products. Sharp retains full right to use the code for his/her own
  19. purpose, assign or donate the code to a third party and to inhibit third
  20. parties from using the code for non <MPEG standard> conforming
  21. products. This copyright notice must be included in all copies or derivative
  22. works.
  23. Copyright (c) 1997.
  24. Module Name:
  25. tps_bfshape.cpp
  26. Abstract:
  27. set volmd, vopmd for backward/forward shape coding
  28.  (for Object based Temporal Scalability)
  29. Revision History:
  30. *************************************************************************/
  31. #include "typeapi.h"
  32. #include "entropy/entropy.hpp"
  33. #include "entropy/huffman.hpp"
  34. #include "entropy/bitstrm.hpp"
  35. #include "global.hpp"
  36. #include "mode.hpp"
  37. #include "codehead.h"
  38. #include "cae.h"
  39. #include "vopses.hpp"
  40. #include "encoder/vopseenc.hpp"
  41. #include "tps_enhcbuf.hpp"
  42. #ifdef __MFC_
  43. #ifdef _DEBUG
  44. #undef THIS_FILE
  45. static char BASED_CODE THIS_FILE[] = __FILE__;
  46. #endif
  47. #define new DEBUG_NEW    
  48. #endif // __MFC_
  49. Int QMatrix [BLOCK_SQUARE_SIZE] = {
  50. 16, 16, 16, 16, 16, 16, 16, 16,
  51. 16, 16, 16, 16, 16, 16, 16, 16,
  52. 16, 16, 16, 16, 16, 16, 16, 16,
  53. 16, 16, 16, 16, 16, 16, 16, 16,
  54. 16, 16, 16, 16, 16, 16, 16, 16,
  55. 16, 16, 16, 16, 16, 16, 16, 16,
  56. 16, 16, 16, 16, 16, 16, 16, 16,
  57. 16, 16, 16, 16, 16, 16, 16, 16
  58. };
  59. Void set_modes(VOLMode* volmd, VOPMode* vopmd) 
  60. {
  61.     ///// set VOL modes
  62. volmd->volType = (VOLtype) BASE_LAYER; // should not be used.
  63. volmd->fAUsage = ONE_BIT;
  64. volmd->bShapeOnly = FALSE; // should be changed to TRUE after checked.
  65. // volmd->iBinaryAlphaTH = rgiBinaryAlphaTH [iVO] * 16;  //magic no. from the vm
  66. volmd->bNoCrChange = TRUE; // mb level binary alpha size conversion disable
  67. volmd->bOriginalForME = TRUE;
  68. volmd->bAdvPredDisable = TRUE;
  69. // Modified by Toshiba (98-04-07) 
  70. // volmd->bErrorResilientDisable  = TRUE;
  71. // End Toshiba
  72. volmd->fQuantizer = Q_H263; // should not be used. H.263/MPEG quantizer.
  73. volmd->bNoGrayQuantUpdate  = FALSE; // should not be used.
  74. volmd->bLoadIntraMatrix = FALSE; // should not be used.
  75. volmd->bLoadInterMatrix = FALSE; // should not be used.
  76. volmd->bLoadIntraMatrixAlpha  = FALSE; // should not be used.
  77. volmd->bLoadInterMatrixAlpha  = FALSE; // should not be used.
  78. volmd->bVPBitTh = -1; // added by Sharp (98/4/13)
  79. memcpy (volmd->rgiIntraQuantizerMatrix, QMatrix, BLOCK_SQUARE_SIZE * sizeof (Int));
  80. // memcpy (volmd->rgiInterQuantizerMatrix, rgppiInterQuantizerMatrix [iLayer][iVO], BLOCK_SQUARE_SIZE * sizeof (Int));
  81. // memcpy (volmd->rgiIntraQuantizerMatrixAlpha, rgppiIntraQuantizerMatrixAlpha [iLayer][iVO], BLOCK_SQUARE_SIZE * sizeof (Int));
  82. // memcpy (volmd->rgiInterQuantizerMatrixAlpha, rgppiInterQuantizerMatrixAlpha [iLayer][iVO], BLOCK_SQUARE_SIZE * sizeof (Int));
  83. volmd->bDeblockFilterDisable = FALSE; // should not be used.
  84. volmd->fEntropyType = huffman; // huffman VLC for texture ? ... may not be used 
  85. // volmd->iPeriodOfIVOP = (rgiNumOfBbetweenPVOP [iVO] + 1) * (rgiNumOfPbetweenIVOP [iVO] + 1); //in temporally sumsampled domain
  86. // volmd->iPeriodOfPVOP = rgiNumOfBbetweenPVOP [iVO] + 1; //in temporally sumsampled domain
  87. // volmd->iTemporalRate = rgiTemporalRate [iVO];
  88. // volmd->iClockRate = SOURCE_FRAME_RATE / volmd->iTemporalRate; //default to frame per second
  89. volmd->bDumpMB = FALSE; // should not be used.
  90. volmd->bTrace = FALSE; // if changed to TRUE, Trace files for backward/forward shape should be prepared like in getInputFiles() and CVideoObjectEncoderTPS().
  91.     ///// set VOP modes
  92. // vopmd->iSearchRangeForward = rguiSearchRange [iLayer][iVO];
  93. // vopmd->iSearchRangeBackward = rguiSearchRange [iLayer][iVO];
  94. // Q-step sizes
  95. vopmd->intStepI = 10; // set temporalily, should not be used after binary_shape_only mode will be integrated.
  96. // vopmd->intStep = rgiStep [iLayer][iVO];
  97. // vopmd->intStepIAlpha = rgiStepIAlpha [iLayer][iVO];
  98. // vopmd->intStepAlpha = rgiStepAlpha [iLayer][iVO];
  99. // vopmd->intDBQuant = rgiStepBCode [iLayer][iVO];
  100. vopmd->iIntraDcSwitchThr        = 0; // threhold to code Intra DC as AC coefs. 0=never do that
  101. vopmd->vopPredType      = IVOP;
  102. }
  103. Void write420_sep(Int num, char *name, PixelC* destY, PixelC* destU, PixelC* destV, Int width, Int height) // modified by Sharp (98/10/26)
  104. {
  105. #ifdef __OUT_ONE_FRAME_
  106.   char file[100];
  107. #endif
  108.   FILE *fp;
  109. #ifndef __OUT_ONE_FRAME_
  110.   fp = fopen(name, "ab");
  111. #else
  112.   sprintf(file, "%s%d", name ,num);
  113.   fp = fopen(file, "wb");
  114. #endif
  115.   fwrite(destY, sizeof (PixelC), width*height, fp);
  116.   fwrite(destU, sizeof (PixelC), width*height/4, fp);
  117.   fwrite(destV, sizeof (PixelC), width*height/4, fp);
  118.   fclose(fp);
  119. }
  120. // begin: added by Sharp (98/10/26)
  121. Void write420_jnt(FILE *fp, PixelC* destY, PixelC* destU, PixelC* destV, Int width, Int height)
  122. {
  123.   fwrite(destY, sizeof (PixelC), width*height, fp);
  124.   fwrite(destU, sizeof (PixelC), width*height/4, fp);
  125.   fwrite(destV, sizeof (PixelC), width*height/4, fp);
  126. }
  127. // end: added by Sharp (98/10/26)
  128. Void write_seg_test(Int num, char *name, PixelC* destY, Int width, Int height)
  129. {
  130.   char file[100];
  131.   FILE *fp;
  132.   sprintf(file, "%s%d", name ,num);
  133.   fp = fopen(file, "a");
  134.   fwrite(destY, sizeof (PixelC), width*height, fp);
  135.   fclose(fp);
  136. }
  137. Void bg_comp_each(PixelC* f_curr, PixelC* f_prev, PixelC* f_next, PixelC* mask_curr, PixelC* mask_prev, PixelC* mask_next, Int curr_t, Int prev_t, Int next_t, Int width, Int height, Int CoreMode)
  138. {
  139.   Int i;
  140.   PixelC* out_image    = new PixelC [width*height];
  141.   PixelC* mask_overlap = new PixelC [width*height];
  142. /* NBIT: change unsigned char to PixelC
  143.   Void pre_pad(unsigned char *mask, unsigned char *curr, int width, int height);
  144. */
  145.   Void pre_pad(PixelC *mask, PixelC *curr, int width, int height);
  146. // begin: added by Sharp (98/3/24)
  147. if ( CoreMode ){
  148. for(i=0; i<width*height; i++)
  149. if(mask_curr[i] == 0 )         // should be used after Type 1 is implemented 
  150. f_curr[i] = f_prev[i];
  151. }
  152. else {
  153. // end: added by Sharp (98/3/24)
  154.   /* ----- put nearest frame ----- */
  155.   if( (abs(curr_t-prev_t) > abs(curr_t-next_t) ) && (abs(abs(curr_t-prev_t) - abs(curr_t-next_t) ) < 1 ))
  156.     for(i=0; i<width*height; i++)
  157. out_image[i]=f_next[i];
  158.   else
  159.     for(i=0; i<width*height; i++)
  160.  out_image[i]=f_prev[i];
  161.   /* ----- perform background composition ----- */
  162.   for(i=0; i<width*height; i++) {
  163.     if(mask_prev[i] > 0 && mask_next[i] == 0)   /* ----- f_next is used ----- */
  164. out_image[i]=f_next[i];
  165.     else if(mask_prev[i] == 0 && mask_next[i] > 0)/* ----- f_prev is used ----- */
  166. out_image[i]=f_prev[i];
  167.     if(mask_prev[i] > 0 && mask_next[i] > 0)   /* ----- overlapped area ----- */
  168. mask_overlap[i]=0;
  169.     else
  170. mask_overlap[i]=1;
  171.   }
  172.   pre_pad(mask_overlap, out_image, width, height); /* for padding */
  173.   /* ----- overlap current frame to back ground ----- */
  174.   for(i=0; i<width*height; i++)
  175.     if(mask_curr[i] == 0 )         // should be used after Type 1 is implemented 
  176.       f_curr[i] = out_image[i];
  177. } // added by Sharp (98/3/24)
  178.   delete out_image;
  179.   delete mask_overlap;
  180. }
  181. Void inv_convertYuv(const CVOPU8YUVBA* pvopcSrc, PixelC* destY, PixelC* destU, PixelC* destV, Int width, Int height)
  182. {
  183.     CoordI x, y;
  184.     Int Fwidth   = pvopcSrc->whereY ().width;
  185.     Int FwidthUV = pvopcSrc->whereUV ().width;
  186.     Int nSkipYPixel = Fwidth  * EXPANDY_REF_FRAME  + EXPANDY_REF_FRAME;
  187.     Int nSkipUVPixel = FwidthUV * EXPANDUV_REF_FRAME + EXPANDUV_REF_FRAME;
  188.     PixelC* ppxlcY = (PixelC*)( (Int)(pvopcSrc->pixelsY ()) + nSkipYPixel );
  189.     PixelC* ppxlcU = (PixelC*)( (Int)(pvopcSrc->pixelsU ()) + nSkipUVPixel );
  190.     PixelC* ppxlcV = (PixelC*)( (Int)(pvopcSrc->pixelsV ()) + nSkipUVPixel );
  191.     PixelC* pdY = destY;    PixelC* pdU = destU;    PixelC* pdV = destV;
  192.     PixelC* psY;    PixelC* psU;    PixelC* psV;
  193.   // convert
  194.     for (y = 0; y < height; y++) {
  195.       psY = ppxlcY;
  196.       for (x = 0; x < width; x++) {
  197. *psY = *pdY;
  198. pdY++;
  199. psY++;
  200.       }
  201.       ppxlcY += Fwidth;
  202.     }
  203.     for (y = 0; y < height/2; y++) {
  204.       psU = ppxlcU;
  205.       for (x = 0; x < width/2; x++) {
  206. *psU = *pdU;
  207. pdU++;
  208. psU++;
  209.       }
  210.       ppxlcU += FwidthUV;
  211.     }
  212.     for (y = 0; y < height/2; y++) {
  213.       psV = ppxlcV;
  214.       for (x = 0; x < width/2; x++) {
  215. *psV = *pdV;
  216. pdV++;
  217. psV++;
  218.       }
  219.       ppxlcV += FwidthUV;
  220.     }
  221. /*
  222.   printf("======== width = %d, height = %dn", width, height);
  223.   FILE *fp;
  224.   fp = fopen("bbb", "w");
  225.   fwrite(destY, sizeof (PixelC), width*height, fp);
  226.   fwrite(destU, sizeof (PixelC), width*height/4, fp);
  227.   fwrite(destV, sizeof (PixelC), width*height/4, fp);
  228.   fclose(fp);
  229.   exit(1);
  230. */
  231. }
  232. Void convertYuv(const CVOPU8YUVBA* pvopcSrc, PixelC* destY, PixelC* destU, PixelC* destV, Int width, Int height)
  233. {
  234.     CoordI x, y;
  235.     Int Fwidth   = pvopcSrc->whereY ().width;
  236.     Int FwidthUV = pvopcSrc->whereUV ().width;
  237.     Int nSkipYPixel = Fwidth  * EXPANDY_REF_FRAME  + EXPANDY_REF_FRAME;
  238.     Int nSkipUVPixel = FwidthUV * EXPANDUV_REF_FRAME + EXPANDUV_REF_FRAME;
  239.     PixelC* ppxlcY = (PixelC*)( (Int)(pvopcSrc->pixelsY ()) + nSkipYPixel );
  240.     PixelC* ppxlcU = (PixelC*)( (Int)(pvopcSrc->pixelsU ()) + nSkipUVPixel );
  241.     PixelC* ppxlcV = (PixelC*)( (Int)(pvopcSrc->pixelsV ()) + nSkipUVPixel );
  242.     PixelC* pdY = destY;    PixelC* pdU = destU;    PixelC* pdV = destV;
  243.     PixelC* psY;    PixelC* psU;    PixelC* psV;
  244.   // convert
  245.     for (y = 0; y < height; y++) {
  246.       psY = ppxlcY;
  247.       for (x = 0; x < width; x++) {
  248. *pdY = *psY;
  249. pdY++;
  250. psY++;
  251.       }
  252.       ppxlcY += Fwidth;
  253.     }
  254.     for (y = 0; y < height/2; y++) {
  255.       psU = ppxlcU;
  256.       for (x = 0; x < width/2; x++) {
  257. *pdU = *psU;
  258. pdU++;
  259. psU++;
  260.       }
  261.       ppxlcU += FwidthUV;
  262.     }
  263.     for (y = 0; y < height/2; y++) {
  264.       psV = ppxlcV;
  265.       for (x = 0; x < width/2; x++) {
  266. *pdV = *psV;
  267. pdV++;
  268. psV++;
  269.       }
  270.       ppxlcV += FwidthUV;
  271.     }
  272. }
  273. Void convertSeg(const CVOPU8YUVBA* pvopcSrc, PixelC* destBY, PixelC* destBUV, Int width, Int height,
  274. Int left, Int right, Int top, Int bottom)
  275. {
  276.     CoordI x, y;
  277.     Int Fwidth  = pvopcSrc->whereY ().width;
  278.     Int sum, color = 0;
  279.     Int nSkipYPixel  = Fwidth  * EXPANDY_REF_FRAME  + EXPANDY_REF_FRAME;
  280.     PixelC* ppxlcBY  = (PixelC*)( (Int)(pvopcSrc->pixelsBY ()) + nSkipYPixel );
  281.     PixelC* pdBY = destBY;    PixelC* pdBUV = destBUV;
  282.     PixelC* psBY;
  283.   // convert
  284.     for (y = 0; y < height; y++) {
  285.       psBY = ppxlcBY;
  286.       for (x = 0; x < width; x++) {
  287. if(left <= x && x < right && top <= y && y < bottom)
  288.   *pdBY = *psBY;
  289. else{
  290.   *pdBY = *psBY = 0; // set zero for out side of VOP rectangle
  291. }
  292. if(*pdBY>0) color = *pdBY;
  293. pdBY++;
  294. psBY++;
  295.       }
  296.       ppxlcBY += Fwidth;
  297.     }
  298. //    if(color == 0){
  299. //      printf("!!! No object !!!n");
  300. //      exit(1);
  301. //    }
  302.     for (y = 0; y < height/2; y++) {
  303.       for (x = 0; x < width/2; x++) {
  304. sum = *(destBY + 2*y*width + 2*x) + *(destBY + (2*y+1)*width + 2*x) +
  305.       *(destBY + 2*y*width + 2*x+1) + *(destBY + (2*y+1)*width + 2*x+1);
  306. if(sum>0)
  307.   *pdBUV = color;
  308. else
  309.   *pdBUV = 0;
  310. pdBUV++;
  311.       }
  312.     }
  313. }
  314. // modified Oct. 1 '97 (by Watanabe and Katata)
  315. /* NBIT: change unsigned char to PixelC
  316. Void pre_pad(unsigned char *mask, unsigned char *curr, int width, int height)
  317. */
  318. Void pre_pad(PixelC *mask, PixelC *curr, int width, int height)
  319. {
  320.   int i, j;
  321.   int flag_cnt = 0;
  322.   int *flag_blk, *mask_blk;
  323.   double *curr_blk;
  324.   double pad_val = 0.0;
  325.   int ic, jc;
  326.   double *hori_blk, *vert_blk;
  327. int *hori_flag_blk, *vert_flag_blk;
  328.   
  329.   flag_blk = (int *)malloc(sizeof(int)*width*height);
  330.   mask_blk = (int *)malloc(sizeof(int)*width*height);
  331.   curr_blk = (double *)malloc(sizeof(double)*width*height);
  332.  // Oct. 1 '97
  333.   hori_blk = (double *)malloc(sizeof(double)*width*height);
  334.   vert_blk = (double *)malloc(sizeof(double)*width*height);
  335.   hori_flag_blk = (int *)malloc(sizeof(int)*width*height);
  336.   vert_flag_blk = (int *)malloc(sizeof(int)*width*height);
  337.   
  338.   
  339.   for(j = 0; j < height; j++)
  340. for(i = 0; i < width; i++) {
  341.   mask_blk[j * width + i] = (mask[j * width + i] != 0);
  342.   if(mask_blk[j * width + i])
  343. hori_blk[j * width + i] = vert_blk[j * width + i] = curr_blk[j * width + i] = (double) curr[j * width + i];
  344. else
  345. hori_blk[j * width + i] = vert_blk[j * width + i] = curr_blk[j * width + i] = 0;
  346. }
  347.   
  348.   for(j = 0; j < height; j++)
  349. for(i = 0; i < width; i++)
  350.   flag_cnt+= (flag_blk[j * width + i] = mask_blk[j * width + i]);
  351.   
  352.   if(flag_cnt == 0)  return;
  353.   
  354. while(flag_cnt != 0) {
  355. for(j = 0; j < height; j++)
  356. for(i = 0; i < width; i++)
  357. hori_flag_blk[j * width + i] = vert_flag_blk[j * width + i] = flag_blk[j * width + i];
  358. for(j = 0; j < height; j++)
  359. for(i = 0; i < width; i++){
  360.   mask_blk[j * width + i] = flag_blk[j * width + i];
  361. hori_blk[j * width + i] = vert_blk[j * width + i] = curr_blk[j * width + i];
  362. }
  363. for(j = 0; j < height; j++) {/* horizontal scan */
  364. for(ic = 1; ic < width; ic++)
  365. if(mask_blk[j * width + ic-1] - mask_blk[j * width + ic] == 1)  break;
  366. for(i = ic; i < width; i++) {
  367. if(mask_blk[j * width + i-1] - mask_blk[j * width + i] == 1)
  368. pad_val = hori_blk[j * width + i-1];
  369. if(!mask_blk[j * width + i]) {
  370. hori_blk[j * width + i]+= pad_val;
  371. hori_flag_blk[j * width + i]++;
  372. }
  373.   }
  374.   for(ic = width-2; ic >= 0; ic--)
  375. if(mask_blk[j * width + ic+1] - mask_blk[j * width + ic] == 1)  break;
  376.   for(i = ic; i >= 0; i--) {
  377. if(mask_blk[j * width + i+1] - mask_blk[j * width + i] == 1)
  378. pad_val = hori_blk[j * width + i+1];
  379. if(!mask_blk[j * width + i]) {
  380. hori_blk[j * width + i]+= pad_val;
  381. hori_flag_blk[j * width + i]++;
  382. }
  383.   }
  384. }/* end of horizontal scan */
  385. for(j = 0; j < height; j++)
  386.   for(i = 0; i < width; i++)
  387. if(hori_flag_blk[j * width + i] != 0) {
  388.   hori_blk[j * width + i] = (int)(hori_blk[j * width + i]/(double) hori_flag_blk[j * width + i]); // Oct.1 '97
  389.   hori_flag_blk[j * width + i]/= hori_flag_blk[j * width + i];
  390. }
  391. for(i = 0; i < width; i++) {/* vertical scan */
  392.   for(jc = 1; jc < height; jc++)
  393. if(mask_blk[(jc-1) * width + i] - mask_blk[jc * width + i] == 1)  break;
  394.   for(j = jc; j < height; j++) {
  395. if(mask_blk[(j-1) * width + i] - mask_blk[j * width + i] == 1)
  396.   pad_val = vert_blk[(j-1) * width + i];
  397. if(!mask_blk[j * width + i]) {
  398. vert_blk[j * width + i]+= pad_val;
  399. vert_flag_blk[j * width + i]++;
  400. }
  401.   }
  402.   for(jc = height-2; jc >= 0; jc--)
  403. if(mask_blk[(jc+1) * width + i] - mask_blk[jc * width + i] == 1)  break;
  404.   for(j = jc; j >= 0; j--) {
  405. if(mask_blk[(j+1) * width + i] - mask_blk[j * width + i] == 1)
  406.   pad_val = vert_blk[(j+1) * width + i];
  407. if(!mask_blk[j * width + i]) {
  408. vert_blk[j * width + i]+= pad_val;
  409. vert_flag_blk[j * width + i]++;
  410. }
  411.   }
  412. }/* end of vertical scan */
  413. for(j = 0; j < height; j++)
  414.   for(i = 0; i < width; i++)
  415. if(vert_flag_blk[j * width + i] != 0) {
  416.   vert_blk[j * width + i] = (int)(vert_blk[j * width + i]/(double) vert_flag_blk[j * width + i]); // Oct.1 '97
  417.   vert_flag_blk[j * width + i]/= vert_flag_blk[j * width + i];
  418. }
  419. for(j = 0; j < height; j++)
  420.   for(i = 0; i < width; i++)
  421. if(hori_flag_blk[j * width + i] == 1 && vert_flag_blk[j * width + i] == 1)
  422. curr_blk[j * width + i] = (int)((hori_blk[j * width + i] + vert_blk[j * width + i])/2.0);
  423. else if (hori_flag_blk[j * width + i] == 1)
  424. curr_blk[j * width + i] = hori_blk[j * width + i];
  425. else if (vert_flag_blk[j * width + i] == 1)
  426. curr_blk[j * width + i] = vert_blk[j * width + i];
  427. flag_cnt = width * height;
  428. for(j = 0; j < height; j++)
  429.   for(i = 0; i < width; i++)
  430. if(hori_flag_blk[j * width + i] == 1 || vert_flag_blk[j * width + i] == 1){
  431. flag_blk[j * width + i] = 1;
  432.   flag_cnt--;
  433. }
  434.   }/* end of while() */
  435.   
  436.   for(j = 0; j < height; j++)
  437. for(i = 0; i < width; i++)
  438.   curr[j * width + i] = (unsigned char) curr_blk[j * width + i];
  439.   free(flag_blk);
  440.   free(mask_blk);
  441.   free(curr_blk);
  442.   free(hori_blk);
  443.   free(vert_blk);
  444.   free(hori_flag_blk);
  445.   free(vert_flag_blk);
  446. }