static bool SegmentSplit( segment_t *p_prev, segment_t **pp_segment, const uint16_t i_start, const uint16_t i_end, const segment_style_t *p_styles ) { segment_t *p_segment_left = NULL, *p_segment_middle = NULL, *p_segment_right = NULL; if ( (*pp_segment)->i_size == 0 ) return false; if ( i_start > i_end ) return false; if ( (size_t)(i_end - i_start) > (*pp_segment)->i_size - 1 ) return false; if ( i_end > (*pp_segment)->i_size - 1 ) return false; SegmentDoSplit( *pp_segment, i_start, i_end, &p_segment_left, &p_segment_middle, &p_segment_right ); if ( !p_segment_middle ) { /* Failed */ SegmentFree( p_segment_left ); SegmentFree( p_segment_right ); return false; } segment_t *p_next = (*pp_segment)->p_next; SegmentFree( *pp_segment ); *pp_segment = ( p_segment_left ) ? p_segment_left : p_segment_middle ; if ( p_prev ) p_prev->p_next = *pp_segment; if ( p_segment_right ) p_segment_right->p_next = p_next; else p_segment_middle->p_next = p_next; p_segment_middle->styles = *p_styles; return true; }
static void SegmentDoSplit( segment_t *p_segment, uint16_t i_start, uint16_t i_end, segment_t **pp_segment_left, segment_t **pp_segment_middle, segment_t **pp_segment_right ) { segment_t *p_segment_left = *pp_segment_left; segment_t *p_segment_right = *pp_segment_right; segment_t *p_segment_middle = *pp_segment_middle; p_segment_left = p_segment_middle = p_segment_right = NULL; if ( (p_segment->i_size - i_start < 1) || (p_segment->i_size - i_end < 1) ) return; if ( i_start > 0 ) { p_segment_left = calloc( 1, sizeof(segment_t) ); if ( !p_segment_left ) goto error; memcpy( &p_segment_left->styles, &p_segment->styles, sizeof(segment_style_t) ); p_segment_left->psz_string = strndup( p_segment->psz_string, i_start ); p_segment_left->i_size = strlen( p_segment_left->psz_string ); } p_segment_middle = calloc( 1, sizeof(segment_t) ); if ( !p_segment_middle ) goto error; memcpy( &p_segment_middle->styles, &p_segment->styles, sizeof(segment_style_t) ); p_segment_middle->psz_string = strndup( p_segment->psz_string + i_start, i_end - i_start + 1 ); p_segment_middle->i_size = strlen( p_segment_middle->psz_string ); if ( i_end < (p_segment->i_size - 1) ) { p_segment_right = calloc( 1, sizeof(segment_t) ); if ( !p_segment_right ) goto error; memcpy( &p_segment_right->styles, &p_segment->styles, sizeof(segment_style_t) ); p_segment_right->psz_string = strndup( p_segment->psz_string + i_end + 1, p_segment->i_size - i_end - 1 ); p_segment_right->i_size = strlen( p_segment_right->psz_string ); } if ( p_segment_left ) p_segment_left->p_next = p_segment_middle; if ( p_segment_right ) p_segment_middle->p_next = p_segment_right; *pp_segment_left = p_segment_left; *pp_segment_middle = p_segment_middle; *pp_segment_right = p_segment_right; return; error: SegmentFree( p_segment_left ); SegmentFree( p_segment_middle ); SegmentFree( p_segment_right ); }
/* * HndDestroyHandleTable * * Cleans up and frees the specified handle table. * */ void HndDestroyHandleTable(HHANDLETABLE hTable) { // fetch the handle table pointer HandleTable *pTable = Table(hTable); // We are going to free the memory for this HandleTable. // Let us reset the copy in g_pHandleTableArray to NULL. // Otherwise, GC will think this HandleTable is still available. Ref_RemoveHandleTable (hTable); // null out the lock pointer and release and free the lock delete pTable->pLock; pTable->pLock = NULL; // fetch the segment list and null out the list pointer TableSegment *pSegment = pTable->pSegmentList; pTable->pSegmentList = NULL; // walk the segment list, freeing the segments as we go while (pSegment) { // fetch the next segment TableSegment *pNextSegment = pSegment->pNextSegment; // free the current one and advance to the next SegmentFree(pSegment); pSegment = pNextSegment; } // free the table's memory HeapFree(g_hProcessHeap, 0, (HLOCAL)pTable); }
SYSCALL int VirtualFree (vm_offset addr) { struct Segment *seg; struct Process *current; current = GetCurrentProcess(); addr = ALIGN_DOWN (addr, PAGE_SIZE); if ((seg = SegmentFind (addr)) == NULL || seg->owner != current) return memoryErr; DisablePreemption(); PmapRemoveRegion (seg); SegmentFree (seg); return 0; }
/***************************************************************************** * Decode: *****************************************************************************/ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block ) { block_t *p_block; subpicture_t *p_spu = NULL; if( ( pp_block == NULL ) || ( *pp_block == NULL ) ) return NULL; p_block = *pp_block; *pp_block = NULL; if( ( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) || p_block->i_buffer < sizeof(uint16_t) ) { block_Release( p_block ); return NULL; } uint8_t *p_buf = p_block->p_buffer; /* Read our raw string and create the styled segment for HTML */ uint16_t i_psz_length = GetWBE( p_buf ); char *psz_subtitle = malloc( i_psz_length + 1 ); if ( !psz_subtitle ) return NULL; memcpy( psz_subtitle, p_block->p_buffer + sizeof(uint16_t), i_psz_length ); psz_subtitle[ i_psz_length ] = '\0'; p_buf += i_psz_length + sizeof(uint16_t); for( uint16_t i=0; i < i_psz_length; i++ ) if ( psz_subtitle[i] == '\r' ) psz_subtitle[i] = '\n'; segment_t *p_segment = calloc( 1, sizeof(segment_t) ); if ( !p_segment ) { free( psz_subtitle ); return NULL; } p_segment->psz_string = strdup( psz_subtitle ); p_segment->i_size = strlen( psz_subtitle ); if ( p_dec->fmt_in.subs.p_style ) { p_segment->styles.i_color = p_dec->fmt_in.subs.p_style->i_font_color; p_segment->styles.i_color |= p_dec->fmt_in.subs.p_style->i_font_alpha << 24; if ( p_dec->fmt_in.subs.p_style->i_style_flags ) p_segment->styles.i_flags = p_dec->fmt_in.subs.p_style->i_style_flags; p_segment->styles.i_fontsize = p_dec->fmt_in.subs.p_style->i_font_size; } if ( !p_segment->psz_string ) { SegmentFree( p_segment ); free( psz_subtitle ); return NULL; } /* Create the subpicture unit */ p_spu = decoder_NewSubpictureText( p_dec ); if( !p_spu ) { free( psz_subtitle ); SegmentFree( p_segment ); return NULL; } subpicture_updater_sys_t *p_spu_sys = p_spu->updater.p_sys; /* Parse our styles */ while( (size_t)(p_buf - p_block->p_buffer) + 8 < p_block->i_buffer ) { uint32_t i_atomsize = GetDWBE( p_buf ); vlc_fourcc_t i_atomtype = VLC_FOURCC(p_buf[4],p_buf[5],p_buf[6],p_buf[7]); p_buf += 8; switch( i_atomtype ) { case VLC_FOURCC('s','t','y','l'): { if ( (size_t)(p_buf - p_block->p_buffer) < 14 ) break; uint16_t i_nbrecords = GetWBE(p_buf); uint16_t i_cur_record = 0; p_buf += 2; while( i_cur_record++ < i_nbrecords ) { if ( (size_t)(p_buf - p_block->p_buffer) < 12 ) break; uint16_t i_start = __MIN( GetWBE(p_buf), i_psz_length - 1 ); uint16_t i_end = __MIN( GetWBE(p_buf + 2), i_psz_length - 1 ); segment_style_t style; style.i_flags = ConvertFlags( p_buf[6] ); style.i_fontsize = p_buf[7]; style.i_color = GetDWBE(p_buf+8) >> 8;// RGBA -> ARGB style.i_color |= (GetDWBE(p_buf+8) & 0xFF) << 24; ApplySegmentStyle( &p_segment, i_start, i_end, &style ); if ( i_nbrecords == 1 ) { if ( p_buf[6] ) { p_spu_sys->style_flags.i_value = ConvertFlags( p_buf[6] ); p_spu_sys->style_flags.b_set = true; } p_spu_sys->i_font_height_abs_to_src = p_buf[7]; p_spu_sys->font_color.i_value = GetDWBE(p_buf+8) >> 8;// RGBA -> ARGB p_spu_sys->font_color.i_value |= (GetDWBE(p_buf+8) & 0xFF) << 24; p_spu_sys->font_color.b_set = true; } p_buf += 12; } } break; case VLC_FOURCC('d','r','p','o'): if ( (size_t)(p_buf - p_block->p_buffer) < 4 ) break; p_spu_sys->i_drop_shadow = __MAX( GetWBE(p_buf), GetWBE(p_buf+2) ); break; case VLC_FOURCC('d','r','p','t'): if ( (size_t)(p_buf - p_block->p_buffer) < 2 ) break; p_spu_sys->i_drop_shadow_alpha = GetWBE(p_buf); break; default: break; } p_buf += i_atomsize; } p_spu->i_start = p_block->i_pts; p_spu->i_stop = p_block->i_pts + p_block->i_length; p_spu->b_ephemer = (p_block->i_length == 0); p_spu->b_absolute = false; p_spu_sys->align = SUBPICTURE_ALIGN_BOTTOM; p_spu_sys->text = psz_subtitle; p_spu_sys->p_htmlsegments = p_segment; block_Release( p_block ); return p_spu; }