static int h264_decodeSPSVUI_hrd(BIT_STREAM_T *pStream, H264_SPS_VUI_T *pVui) { int idx; if((pVui->hrd_cpb_count = bits_readExpGolomb(pStream) + 1) > sizeof(pVui->hrd_cpb) / sizeof(pVui->hrd_cpb[0])) { LOG(X_ERROR("SPS VUI HRD parameter cpb_count %d exceeds %d"), pVui->hrd_cpb_count, sizeof(pVui->hrd_cpb) / sizeof(pVui->hrd_cpb[0])); return H264_RC_ERR; } pVui->hrd_bit_rate_scale = bits_read(pStream, 4); pVui->hrd_cpb_size_scale = bits_read(pStream, 4); for(idx = 0; idx < pVui->hrd_cpb_count; idx++) { pVui->hrd_cpb[idx].hrd_bit_rate_val_min1 = bits_readExpGolomb(pStream); pVui->hrd_cpb[idx].hrd_cpb_size_val_min1 = bits_readExpGolomb(pStream); pVui->hrd_cpb[idx].hrd_cbr_flag = bits_read(pStream, 1); } pVui->hrd_initial_cpb_removal_delay_len = bits_read(pStream, 5) + 1; pVui->hrd_cpb_removal_delay_len = bits_read(pStream, 5) + 1; pVui->hrd_dpb_output_delay_len = bits_read(pStream, 5) + 1; pVui->hrd_time_offset_len = bits_read(pStream, 5); return H264_RC_OK; }
static int h264_decodeVUI(BIT_STREAM_T *pStream, H264_SPS_VUI_T *pVui) { if((pVui->aspect_ratio_info_present = bits_read(pStream, 1))) { if((pVui->aspect_ratio_idc = bits_read(pStream, 8)) == 255) { // MPEG4-10 Table E-1 pVui->aspect_ratio_sar_width = bits_read(pStream, 16); pVui->aspect_ratio_sar_height = bits_read(pStream, 16); } } if((pVui->overscan_info_present = bits_read(pStream, 1))) { pVui->overscan_appropriate = bits_read(pStream, 1); } if((pVui->video_signal_type_present = bits_read(pStream, 1))) { pVui->video_format = bits_read(pStream, 3); pVui->video_full_range = bits_read(pStream, 1); if((pVui->color_desc_present = bits_read(pStream, 1))) { pVui->color_primaries = bits_read(pStream, 8); pVui->color_transfer_characteristics = bits_read(pStream, 8); pVui->color_matrix = bits_read(pStream, 8); } } if((pVui->chroma_loc_info_present = bits_read(pStream, 1))) { pVui->chroma_sample_top = bits_readExpGolomb(pStream); pVui->chroma_sample_bottom = bits_readExpGolomb(pStream); } if((pVui->timing_info_present = bits_read(pStream, 1))) { pVui->timing_num_units_in_tick = bits_read(pStream, 32); pVui->timing_timescale = bits_read(pStream, 32); pVui->timing_fixed_frame_rate = bits_read(pStream, 1); } if((pVui->nal_hrd_params = bits_read(pStream, 1))) { if(h264_decodeSPSVUI_hrd(pStream, pVui) < 0) { return H264_RC_ERR; } } if((pVui->vcl_hrd_params = bits_read(pStream, 1))) { if(h264_decodeSPSVUI_hrd(pStream, pVui) < 0) { return H264_RC_ERR; } } if(pVui->nal_hrd_params || pVui->vcl_hrd_params) { pVui->low_delay_hrd_flag = bits_read(pStream, 1); } pVui->pic_struct_present_flag = bits_read(pStream, 1); if((pVui->bitstream_restriction = bits_read(pStream, 1))) { pVui->motion_vec_over_pic_boundary = bits_read(pStream, 1); pVui->max_bytes_per_pic_denom = bits_readExpGolomb(pStream); pVui->max_bits_per_pic_denom = bits_readExpGolomb(pStream); pVui->log2_max_mv_len_horiz = bits_readExpGolomb(pStream); pVui->log2_max_mv_len_vert = bits_readExpGolomb(pStream); pVui->num_reorder_frames = bits_readExpGolomb(pStream); pVui->max_dec_frame_buffering = bits_readExpGolomb(pStream); } return H264_RC_OK; }
static int h264_decodeSlice(H264_DECODER_CTXT_T *pCtxt, BIT_STREAM_T *pStream, uint8_t nalType) { int first_mb_in_slice = 0; unsigned int slice_type = 0; unsigned int slice_type0 = 0; unsigned int pps_id = 0; unsigned int frame_idx = 0; int idr_pic_id = 0; int picture_structure = 0; int tmp; H264_NAL_SPS_T *pSps; H264_NAL_PPS_T *pPps; if(pStream->sz - pStream->byteIdx < 4) { LOG(X_WARNING("Slice given length to decode below minimum: %d"), pStream->sz - pStream->byteIdx); // Fail gracefully to accomodate empty NALs return H264_RC_OK; } pCtxt->sliceIdx++; first_mb_in_slice = bits_readExpGolomb(pStream); if((slice_type0 = slice_type = (unsigned int) bits_readExpGolomb(pStream)) > H264_SLICE_TYPE_SI) { slice_type -= (H264_SLICE_TYPE_SI + 1); } if(slice_type > H264_SLICE_TYPE_SI) { LOG(X_WARNING("Invalid slice type: %d"), slice_type); return H264_RC_ERR; } pCtxt->lastSliceType = slice_type; if((pps_id = bits_readExpGolomb(pStream)) >= H264_MAX_PPS_CNT || !pCtxt->pps[pps_id].is_ok) { LOG(X_WARNING("Slice references unknown pps:%d"), pps_id); return -1; } pPps = &pCtxt->pps[pps_id]; pSps = &pCtxt->sps[ pPps->seq_param_set_id ]; if((frame_idx = bits_read(pStream, pSps->log2_max_frame_num)) != pCtxt->frameIdx) { pCtxt->frameIdx = frame_idx; pCtxt->sliceIdx = 0; } if(!pSps->frame_mbs_only_flag && bits_read(pStream, 1)) { // field pic flag picture_structure = 1 + bits_read(pStream, 1); // pic_order_cnt_lsb } else { picture_structure = 3; } if(nalType == NAL_TYPE_IDR) { idr_pic_id = bits_readExpGolomb(pStream); } if(pSps->pic_order_cnt_type == 0) { pCtxt->picOrderCnt = bits_read(pStream, pSps->log2_max_pic_order_cnt_lsb); if(pPps->pic_order_present_flag == 1 && picture_structure == 3) { bits_readExpGolomb(pStream); // delta_poc_bottom } } else if(pSps->pic_order_cnt_type == 1 && !pSps->pic_delta_pic_order) { bits_readExpGolomb(pStream); // delta_poc[0] if(pPps->pic_order_present_flag == 1 && picture_structure == 3) { bits_readExpGolomb(pStream); // delta_poc[1] } } if(pPps->redundant_pic_cnt_present_flag) { bits_readExpGolomb(pStream); // bits_readExpGolomb(pStream); } //fprintf(stderr, "slice: first_mb_in_slice:%d, slice_type:%d,%d, sps:%d, pps:%d, fridx:%d, picstruct:%d, idr_pic_id:%d, sps poctype:%d, poc:%d, pps_pic_order_present:%d, pps_redundant_pic_cnt_present:%d\n", first_mb_in_slice, slice_type, slice_type0, pPps->seq_param_set_id, pps_id, frame_idx, picture_structure, idr_pic_id, pSps->pic_order_cnt_type, pCtxt->picOrderCnt, pPps->pic_order_present_flag, pPps->redundant_pic_cnt_present_flag); if(slice_type != H264_SLICE_TYPE_I) { if(slice_type != H264_SLICE_TYPE_B) { bits_read(pStream, 1); // direct_spatial_mv_pred } if((bits_read(pStream, 1))) { // num_ref_idx_active_override_flag bits_readExpGolomb(pStream); // ref_count[0] + 1 if(slice_type != H264_SLICE_TYPE_B) { bits_readExpGolomb(pStream); // ref_count[1] + 1 } } if(pPps->entropy_coding_mode_flag) { bits_readExpGolomb(pStream); } } if(slice_type == H264_SLICE_TYPE_SP) { bits_read(pStream, 1); // sp_for_switch_flag } if(slice_type == H264_SLICE_TYPE_SP || slice_type == H264_SLICE_TYPE_SI) { bits_readExpGolomb(pStream); // slice_qs_delta } if(pPps->deblocking_filter_control_present_flag) { tmp = bits_readExpGolomb(pStream); if(tmp < 2) { tmp^=1; } if(tmp) { bits_readExpGolomb(pStream); // slice_alpha_c0_offset bits_readExpGolomb(pStream); // slice_beta_offset } } return H264_RC_OK; }
int h264_decodeSPS(BIT_STREAM_T *pStream, H264_NAL_SPS_T *pSps) { int idx; uint8_t profile_idc; uint8_t level_idc; uint8_t constraint; unsigned int sps_id; if(pStream->sz - pStream->byteIdx < 8) { LOG(X_ERROR("SPS length to decode below minimum: %d"), pStream->sz - pStream->byteIdx); return H264_RC_ERR; } profile_idc = bits_read(pStream, 8); constraint = bits_read(pStream, 8); // 3 bits constraints set , 5 bits reserved level_idc = bits_read(pStream, 8); if((sps_id = bits_readExpGolomb(pStream)) >= H264_MAX_SPS_CNT) { LOG(X_ERROR("SPS id is invalid:%d"), sps_id); return H264_RC_ERR; } memset(pSps, 0, sizeof(H264_NAL_SPS_T)); pSps->profile_id = profile_idc; pSps->constraint = constraint; pSps->level_id = level_idc; pSps->seq_param_set_id = sps_id; if(profile_idc >= H264_PROFILE_HIGH) { if((pSps->chroma_format_idc = bits_readExpGolomb(pStream)) == 3) { pSps->residual_color_transform = bits_read(pStream, 1); } else if(pSps->chroma_format_idc > 3) { LOG(X_ERROR("SPS chroma_format out of range: %d"), pSps->chroma_format_idc); return H264_RC_ERR; } pSps->bit_depth_luma = bits_readExpGolomb(pStream) + 8; pSps->bit_depth_chroma = bits_readExpGolomb(pStream) + 8; pSps->qprime_y_zero_transform_bypass = bits_read(pStream, 1); pSps->scaling_matrix_present = bits_read(pStream, 1); if(pSps->scaling_matrix_present) { LOG(X_ERROR("SPS scaling matrix decode not implemented for high profiles")); return H264_RC_ERR; } } else { pSps->chroma_format_idc = 1; } if((pSps->log2_max_frame_num = bits_readExpGolomb(pStream) + 4) < 4 || pSps->log2_max_frame_num > 16) { LOG(X_ERROR("SPS log2_max_frame_num: %d out of range"), pSps->log2_max_frame_num); return H264_RC_ERR; } if((pSps->pic_order_cnt_type = bits_readExpGolomb(pStream)) == 0) { if((pSps->log2_max_pic_order_cnt_lsb = bits_readExpGolomb(pStream) + 4) < 4 || pSps->log2_max_pic_order_cnt_lsb > 16) { LOG(X_ERROR("SPS log2_max_pic_order_cnt_lsb: %d out of range"), pSps->log2_max_pic_order_cnt_lsb); return H264_RC_ERR; } } else if(pSps->pic_order_cnt_type == 1) { pSps->pic_delta_pic_order = bits_read(pStream, 1); pSps->pic_offset_non_ref_pic = bits_readExpGolomb(pStream); pSps->pic_offset_top_to_bottom = bits_readExpGolomb(pStream); pSps->pic_num_ref_frames_in_pic_order_cnt_cycle = bits_readExpGolomb(pStream); if(pSps->pic_num_ref_frames_in_pic_order_cnt_cycle > sizeof(pSps->pic_offset_for_ref_frame) / sizeof(pSps->pic_offset_for_ref_frame[0])) { LOG(X_ERROR("SPS num_ref_frames_in_pic_order_cnt_cycle %d greater than %d."), pSps->pic_num_ref_frames_in_pic_order_cnt_cycle, sizeof(pSps->pic_offset_for_ref_frame) / sizeof(pSps->pic_offset_for_ref_frame[0])); return H264_RC_ERR; } for(idx = 0; idx < pSps->pic_num_ref_frames_in_pic_order_cnt_cycle; idx++) { pSps->pic_offset_for_ref_frame[idx] = bits_readExpGolomb(pStream); } } else if(pSps->pic_order_cnt_type != 2) { LOG(X_ERROR("SPS pic_order_cnt_type:%d out of range"), pSps->pic_order_cnt_type); return H264_RC_ERR; } pSps->num_ref_frames = bits_readExpGolomb(pStream); pSps->gaps_in_frame_num_val_allowed_flag = bits_read(pStream, 1); pSps->pic_width_in_mbs = bits_readExpGolomb(pStream) + 1; pSps->pic_height_in_mbs = bits_readExpGolomb(pStream) + 1; //fprintf(stderr, "RES:%dx%d\n", pSps->pic_width_in_mbs*16, pSps->pic_height_in_mbs*16); if((pSps->frame_mbs_only_flag = bits_read(pStream, 1)) == 0) { pSps->mb_adaptive_frame_field_flag = bits_read(pStream, 1); } pSps->direct_8x8_inference_flag = bits_read(pStream, 1); if((pSps->frame_cropping = bits_read(pStream, 1))) { pSps->crop_left = bits_readExpGolomb(pStream); pSps->crop_right = bits_readExpGolomb(pStream); // // Crop should be no bigger than 1mb after applying multiplier of 2px (or 4px for interlaced) // if((pSps->crop_top = bits_readExpGolomb(pStream)) > 7) { pSps->crop_top = 7; } else if(pSps->frame_mbs_only_flag == 0 && pSps->crop_top > 3) { pSps->crop_top = 3; } if((pSps->crop_bottom = bits_readExpGolomb(pStream)) > 7) { pSps->crop_bottom = 7; } else if(pSps->frame_mbs_only_flag == 0 && pSps->crop_bottom > 3) { pSps->crop_bottom = 3; } } else { pSps->crop_left = 0; pSps->crop_right = 0; pSps->crop_top = 0; pSps->crop_bottom = 0; } if((pSps->vui.params_present_flag = bits_read(pStream, 1))) { if(h264_decodeVUI(pStream, &pSps->vui) != 0) { return H264_RC_ERR; } } pSps->is_ok = 1; return H264_RC_OK; }
char * lzw_decode(char *alphabet, data *d) { char **decode_dict = malloc(64); int index = 1; int len = 6; int index_max = 64; for (int i = 0; i < strlen(alphabet); i++) { char *c = malloc(2); c[0] = alphabet[i]; c[1] = '\0'; decode_dict[index++] = c; } int pt_len = 100; int total_len = 0; char *plaintext = malloc(pt_len); char *curr = plaintext; if (plaintext == NULL) printf("PT NULL!!"); else if (curr == NULL) printf("CURR NULL!"); // Get the sequence corresponding to the code int code = (int) bits_read(d, len); printf("Got code: %d %d ...", index, code); char *last_seq = NULL; while (code != 0) { char *seq = decode_dict[code]; printf("%s", seq); if (code >= index) { // Edge case when cScSc where c is a character and S is a string int seq_len = strlen(last_seq) + 1; seq = malloc(seq_len + 1); strncpy(seq, last_seq, seq_len - 1); seq[seq_len - 1] = last_seq[0]; seq[seq_len] = '\0'; decode_dict[index++] = seq; total_len += seq_len; strncpy(curr, seq, seq_len); curr += seq_len; } else { printf("Got %d %s\n", code, seq); int seq_len = strlen(seq); // Increase size of result if needed if (pt_len < total_len + seq_len) { pt_len *= 2; plaintext = realloc(plaintext, pt_len); curr = plaintext + total_len; } else { printf("Not needed..."); } // Copy sequence into result total_len += seq_len; printf("Copying %s %d into curr %s... ", seq, seq_len, curr); strncpy(curr, seq, seq_len); curr += seq_len; printf("So far: %s\n", plaintext); // Add new entry to dict which is concat of last_seq and first char of current seq if (last_seq != NULL) { int new_seq_len = strlen(last_seq) + 2; char *new_seq = malloc(new_seq_len); strncpy(new_seq, last_seq, new_seq_len - 2); new_seq[new_seq_len - 2] = seq[0]; new_seq[new_seq_len - 1] = '\0'; decode_dict[index++] = new_seq; if (index >= index_max) { index_max *= 2; decode_dict = realloc(decode_dict, index_max); len++; } } } last_seq = seq; code = (int)bits_read(d, len); } plaintext[total_len] = '\0'; for (int i = 0; i < index; i++) free(decode_dict[i]); free(decode_dict); return plaintext; }