00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "contributors.h"
00016 #include "global.h"
00017 #include "image.h"
00018 #include "input.h"
00019 #include "output.h"
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 void img2buf (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes, int crop_left, int crop_right, int crop_top, int crop_bottom)
00046 {
00047 int i,j;
00048
00049 int twidth = size_x - crop_left - crop_right;
00050 int theight = size_y - crop_top - crop_bottom;
00051
00052 int size = 0;
00053
00054 unsigned char ui8;
00055 uint16 tmp16, ui16;
00056 unsigned long tmp32, ui32;
00057
00058 if (( sizeof(char) == sizeof (imgpel)) && ( sizeof(char) == symbol_size_in_bytes))
00059 {
00060
00061 if (crop_left == 0 && crop_top == 0 && crop_right == 0 && crop_bottom == 0)
00062 memcpy(buf,&(imgX[0][0]), twidth * theight);
00063 else
00064 {
00065 for(i=0;i<theight;i++)
00066 memcpy(buf + crop_left + (i * twidth),&(imgX[i + crop_top][crop_left]), twidth);
00067 }
00068 }
00069 else
00070 {
00071
00072 if (testEndian())
00073 {
00074
00075 switch (symbol_size_in_bytes)
00076 {
00077 case 1:
00078 {
00079 for(i=crop_top;i<size_y-crop_bottom;i++)
00080 for(j=crop_left;j<size_x-crop_right;j++)
00081 {
00082 ui8 = (unsigned char) (imgX[i][j]);
00083 buf[(j-crop_left+((i-crop_top)*(twidth)))] = ui8;
00084 }
00085 break;
00086 }
00087 case 2:
00088 {
00089 for(i=crop_top;i<size_y-crop_bottom;i++)
00090 for(j=crop_left;j<size_x-crop_right;j++)
00091 {
00092 tmp16 = (uint16) (imgX[i][j]);
00093 ui16 = (tmp16 >> 8) | ((tmp16&0xFF)<<8);
00094 memcpy(buf+((j-crop_left+((i-crop_top)*(twidth)))*2),&(ui16), 2);
00095 }
00096 break;
00097 }
00098 case 4:
00099 {
00100 for(i=crop_top;i<size_y-crop_bottom;i++)
00101 for(j=crop_left;j<size_x-crop_right;j++)
00102 {
00103 tmp32 = (unsigned long) (imgX[i][j]);
00104 ui32 = ((tmp32&0xFF00)<<8) | ((tmp32&0xFF)<<24) | ((tmp32&0xFF0000)>>8) | ((tmp32&0xFF000000)>>24);
00105 memcpy(buf+((j-crop_left+((i-crop_top)*(twidth)))*4),&(ui32), 4);
00106 }
00107 break;
00108 }
00109 default:
00110 {
00111 error ("writing only to formats of 8, 16 or 32 bit allowed on big endian architecture", 500);
00112 break;
00113 }
00114 }
00115
00116 }
00117 else
00118 {
00119
00120 if (sizeof (imgpel) < symbol_size_in_bytes)
00121 {
00122
00123 size = sizeof (imgpel);
00124
00125 memset (buf, 0, (twidth*theight*symbol_size_in_bytes));
00126 }
00127 else
00128 {
00129 size = symbol_size_in_bytes;
00130 }
00131
00132 for(i=crop_top;i<size_y-crop_bottom;i++)
00133 {
00134 int i_pos = (i-crop_top)*(twidth) - crop_left;
00135 for(j=crop_left;j<size_x-crop_right;j++)
00136 {
00137 memcpy(buf+((j + i_pos)*symbol_size_in_bytes),&(imgX[i][j]), size);
00138 }
00139 }
00140 }
00141 }
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 void write_picture(StorablePicture *p, FrameFormat *output, int p_out)
00157 {
00158 write_out_picture(p, output, p_out);
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 void write_out_picture(StorablePicture *p, FrameFormat *output, int p_out)
00174 {
00175 int SubWidthC [4]= { 1, 2, 2, 1};
00176 int SubHeightC [4]= { 1, 2, 1, 1};
00177
00178 int ret;
00179
00180 int crop_left, crop_right, crop_top, crop_bottom;
00181 int symbol_size_in_bytes = output->pic_unit_size_shift3;
00182 Boolean rgb_output = (Boolean) (output->color_model != CM_YUV && output->yuv_format == YUV444);
00183 unsigned char *buf;
00184
00185 if (p->non_existing)
00186 return;
00187
00188 if (p_out == -1)
00189 return;
00190
00191 if (p->frame_cropping_flag)
00192 {
00193 crop_left = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_left_offset;
00194 crop_right = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_right_offset;
00195 crop_top = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
00196 crop_bottom = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
00197 }
00198 else
00199 {
00200 crop_left = crop_right = crop_top = crop_bottom = 0;
00201 }
00202
00203
00204
00205
00206 buf = malloc (p->size_x * p->size_y * symbol_size_in_bytes);
00207 if (NULL==buf)
00208 {
00209 no_mem_exit("write_out_picture: buf");
00210 }
00211
00212 if(rgb_output)
00213 {
00214 crop_left = p->frame_cropping_rect_left_offset;
00215 crop_right = p->frame_cropping_rect_right_offset;
00216 crop_top = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
00217 crop_bottom = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
00218
00219 img2buf (p->imgUV[1], buf, p->size_x_cr, p->size_y_cr, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
00220 ret = write(p_out, buf, (p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)*symbol_size_in_bytes);
00221 if (ret != ((p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)*symbol_size_in_bytes))
00222 {
00223 error ("write_out_picture: error writing to RGB output file.", 500);
00224 }
00225
00226 if (p->frame_cropping_flag)
00227 {
00228 crop_left = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_left_offset;
00229 crop_right = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_right_offset;
00230 crop_top = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
00231 crop_bottom = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
00232 }
00233 else
00234 {
00235 crop_left = crop_right = crop_top = crop_bottom = 0;
00236 }
00237 }
00238
00239 img2buf (p->imgY, buf, p->size_x, p->size_y, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
00240 ret = write(p_out, buf, (p->size_y-crop_bottom-crop_top)*(p->size_x-crop_right-crop_left)*symbol_size_in_bytes);
00241 if (ret != ((p->size_y-crop_bottom-crop_top)*(p->size_x-crop_right-crop_left)*symbol_size_in_bytes))
00242 {
00243 error ("write_out_picture: error writing to YUV output file.", 500);
00244 }
00245
00246 if (p->chroma_format_idc != YUV400)
00247 {
00248 crop_left = p->frame_cropping_rect_left_offset;
00249 crop_right = p->frame_cropping_rect_right_offset;
00250 crop_top = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
00251 crop_bottom = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
00252
00253 img2buf (p->imgUV[0], buf, p->size_x_cr, p->size_y_cr, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
00254 ret = write(p_out, buf, (p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)* symbol_size_in_bytes);
00255 if (ret != ((p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)* symbol_size_in_bytes))
00256 {
00257 error ("write_out_picture: error writing to YUV output file.", 500);
00258 }
00259
00260 if (!rgb_output)
00261 {
00262 img2buf (p->imgUV[1], buf, p->size_x_cr, p->size_y_cr, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
00263 ret = write(p_out, buf, (p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)*symbol_size_in_bytes);
00264 if (ret != ((p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)*symbol_size_in_bytes))
00265 {
00266 error ("write_out_picture: error writing to YUV output file.", 500);
00267 }
00268 }
00269 }
00270
00271 free(buf);
00272
00273
00274 }
00275
00276
00277
00278
00279
00280
00281
00282 void init_out_buffer(ImageParameters *p_Img)
00283 {
00284 p_Img->out_buffer = alloc_frame_store();
00285 }
00286
00287
00288
00289
00290
00291
00292
00293 void uninit_out_buffer(ImageParameters *p_Img, InputParameters *p_Inp)
00294 {
00295 free_frame_store(p_Img, p_Inp, p_Img->out_buffer);
00296 p_Img->out_buffer=NULL;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305 void clear_picture(ImageParameters *p_Img, StorablePicture *p)
00306 {
00307 int i;
00308
00309 if (p_Img->bitdepth_luma == 8)
00310 {
00311
00312
00313 for(i=0;i<p->size_y;i++)
00314 memset(p->imgY[i], p_Img->dc_pred_value_comp[0], p->size_x*sizeof(imgpel));
00315 }
00316 else
00317 {
00318 int j;
00319 for(i=0;i < p->size_y; i++)
00320 for(j=0;j < p->size_x; j++)
00321 p->imgY[i][j] = (imgpel) p_Img->dc_pred_value_comp[0];
00322 }
00323
00324 if (p_Img->bitdepth_chroma == 8)
00325 {
00326 for(i=0;i<p->size_y_cr;i++)
00327 memset(p->imgUV[0][i], p_Img->dc_pred_value_comp[1], p->size_x_cr*sizeof(imgpel));
00328 for(i=0;i<p->size_y_cr;i++)
00329 memset(p->imgUV[1][i], p_Img->dc_pred_value_comp[2], p->size_x_cr*sizeof(imgpel));
00330 }
00331 else
00332 {
00333 int k, j;
00334 for (k = 0; k < 2; k++)
00335 {
00336 for(i=0;i<p->size_y_cr;i++)
00337 for(j=0;j < p->size_x_cr; j++)
00338 p->imgUV[k][i][j] = (imgpel) p_Img->dc_pred_value_comp[1];
00339 }
00340 }
00341 }
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 void write_unpaired_field(ImageParameters *p_Img, InputParameters *p_Inp, FrameStore* fs, FrameFormat *output, int p_out)
00361 {
00362 StorablePicture *p;
00363 assert (fs->is_used<3);
00364 if(fs->is_used &1)
00365 {
00366
00367
00368 p = fs->top_field;
00369 fs->bottom_field = alloc_storable_picture(p_Img, p_Inp, BOTTOM_FIELD, p->size_x, p->size_y, p->size_x_cr, p->size_y_cr);
00370 fs->bottom_field->chroma_format_idc = p->chroma_format_idc;
00371 fs->bottom_field->chroma_mask_mv_x = p->chroma_mask_mv_x;
00372 fs->bottom_field->chroma_mask_mv_y = p->chroma_mask_mv_y;
00373 fs->bottom_field->chroma_shift_x = p->chroma_shift_x;
00374 fs->bottom_field->chroma_shift_y = p->chroma_shift_y;
00375
00376 clear_picture(p_Img, fs->bottom_field);
00377 dpb_combine_field_yuv(p_Img, p_Inp, fs);
00378 write_picture (fs->frame, output, p_out);
00379 }
00380
00381 if(fs->is_used &2)
00382 {
00383
00384
00385 p = fs->bottom_field;
00386 fs->top_field = alloc_storable_picture(p_Img, p_Inp, TOP_FIELD, p->size_x, p->size_y, p->size_x_cr, p->size_y_cr);
00387 clear_picture(p_Img, fs->top_field);
00388 fs->top_field->chroma_format_idc = p->chroma_format_idc;
00389 fs->top_field->chroma_mask_mv_x = p->chroma_mask_mv_x;
00390 fs->top_field->chroma_mask_mv_y = p->chroma_mask_mv_y;
00391 fs->top_field->chroma_shift_x = p->chroma_shift_x;
00392 fs->top_field->chroma_shift_y = p->chroma_shift_y;
00393
00394 clear_picture(p_Img, fs->top_field);
00395 fs ->top_field->frame_cropping_flag = fs->bottom_field->frame_cropping_flag;
00396 if(fs ->top_field->frame_cropping_flag)
00397 {
00398 fs ->top_field->frame_cropping_rect_top_offset = fs->bottom_field->frame_cropping_rect_top_offset;
00399 fs ->top_field->frame_cropping_rect_bottom_offset = fs->bottom_field->frame_cropping_rect_bottom_offset;
00400 fs ->top_field->frame_cropping_rect_left_offset = fs->bottom_field->frame_cropping_rect_left_offset;
00401 fs ->top_field->frame_cropping_rect_right_offset = fs->bottom_field->frame_cropping_rect_right_offset;
00402 }
00403 dpb_combine_field_yuv(p_Img, p_Inp, fs);
00404 write_picture (fs->frame, output, p_out);
00405 }
00406
00407 fs->is_used=3;
00408 }
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 void flush_direct_output(ImageParameters *p_Img, InputParameters *p_Inp, FrameFormat *output, int p_out)
00425 {
00426 write_unpaired_field(p_Img, p_Inp, p_Img->out_buffer, output, p_out);
00427
00428 free_storable_picture(p_Img, p_Inp, p_Img->out_buffer->frame);
00429 p_Img->out_buffer->frame = NULL;
00430 free_storable_picture(p_Img, p_Inp, p_Img->out_buffer->top_field);
00431 p_Img->out_buffer->top_field = NULL;
00432 free_storable_picture(p_Img, p_Inp, p_Img->out_buffer->bottom_field);
00433 p_Img->out_buffer->bottom_field = NULL;
00434 p_Img->out_buffer->is_used = 0;
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454 void write_stored_frame( ImageParameters *p_Img, InputParameters *p_Inp, FrameStore *fs, FrameFormat *output, int p_out)
00455 {
00456
00457 flush_direct_output(p_Img, p_Inp, output, p_out);
00458
00459 if (fs->is_used<3)
00460 {
00461 write_unpaired_field(p_Img, p_Inp, fs, output, p_out);
00462 }
00463 else
00464 {
00465 write_picture(fs->frame, output, p_out);
00466 }
00467
00468 fs->is_output = 1;
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 void direct_output(ImageParameters *p_Img, InputParameters *p_Inp, StorablePicture *p, FrameFormat *output, int p_out)
00490 {
00491 switch ( p->structure )
00492 {
00493 case FRAME:
00494
00495
00496 flush_direct_output(p_Img, p_Inp, output, p_out);
00497 write_picture (p, output, p_out);
00498 free_storable_picture(p_Img, p_Inp, p);
00499 return;
00500 break;
00501 case TOP_FIELD:
00502 if (p_Img->out_buffer->is_used &1)
00503 flush_direct_output(p_Img, p_Inp, output, p_out);
00504 p_Img->out_buffer->top_field = p;
00505 p_Img->out_buffer->is_used |= 1;
00506 break;
00507 case BOTTOM_FIELD:
00508 if (p_Img->out_buffer->is_used &2)
00509 flush_direct_output(p_Img, p_Inp, output, p_out);
00510 p_Img->out_buffer->bottom_field = p;
00511 p_Img->out_buffer->is_used |= 2;
00512 break;
00513 default:
00514 printf("invalid picture type\n");
00515 break;
00516 }
00517
00518 if (p_Img->out_buffer->is_used == 3)
00519 {
00520
00521 dpb_combine_field_yuv(p_Img, p_Inp, p_Img->out_buffer);
00522 write_picture (p_Img->out_buffer->frame, output, p_out);
00523 free_storable_picture(p_Img, p_Inp, p_Img->out_buffer->frame);
00524 p_Img->out_buffer->frame = NULL;
00525 free_storable_picture(p_Img, p_Inp, p_Img->out_buffer->top_field);
00526 p_Img->out_buffer->top_field = NULL;
00527 free_storable_picture(p_Img, p_Inp, p_Img->out_buffer->bottom_field);
00528 p_Img->out_buffer->bottom_field = NULL;
00529 p_Img->out_buffer->is_used = 0;
00530 }
00531 }
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551 void direct_output_paff(ImageParameters *p_Img, InputParameters *p_Inp, StorablePicture *p, FrameFormat *output, int p_out)
00552 {
00553 printf("Warning!!! Frame can't fit in DPB. Displayed out of sequence.\n");
00554 free_storable_picture(p_Img, p_Inp, p_Img->out_buffer->frame);
00555 p_Img->out_buffer->frame = NULL;
00556 free_storable_picture(p_Img, p_Inp, p_Img->out_buffer->top_field);
00557 p_Img->out_buffer->top_field = NULL;
00558 free_storable_picture(p_Img, p_Inp, p_Img->out_buffer->bottom_field);
00559 p_Img->out_buffer->bottom_field = NULL;
00560 p_Img->out_buffer->is_used = 0;
00561
00562 direct_output(p_Img, p_Inp, p, output, p_out);
00563 }