forked from minhngoc25a/freetype2
[woff2] Copy un-transformed tables to sfnt stream.
Copy un-transformed tables to the sfnt stream. * src/sfnt/sfwoff2.c: (WRITE_SFNT_BUF): New macro. (write_buf): New function. Extend memory of `dst' buffer and copy bytes from `src'. (compute_ULong_sum): New function. Calculate checksum of table. (woff2_uncompress): Change `FT_Byte* sfnt' to `FT_Byte** sfnt_bytes'. This has been done because we reallocate memory to `sfnt' multiple times, which may change the pointer value of `sfnt'. This new pointer must be propogated back to the caller. Same reason for using a double pointer in `write_buf'. * src/sfnt/woff2tags.h: Define default max size to prevent overflow.
This commit is contained in:
parent
c325089c2f
commit
7bf104e759
|
@ -64,6 +64,8 @@
|
||||||
\
|
\
|
||||||
} while ( 0 )
|
} while ( 0 )
|
||||||
|
|
||||||
|
#define WRITE_SFNT_BUF( buf, s ) \
|
||||||
|
write_buf( &sfnt, &dest_offset, buf, s, memory )
|
||||||
|
|
||||||
static void
|
static void
|
||||||
stream_close( FT_Stream stream )
|
stream_close( FT_Stream stream )
|
||||||
|
@ -182,6 +184,41 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static FT_Error
|
||||||
|
write_buf( FT_Byte** dst_bytes,
|
||||||
|
FT_ULong* offset,
|
||||||
|
FT_Byte* src,
|
||||||
|
FT_ULong size,
|
||||||
|
FT_Memory memory )
|
||||||
|
{
|
||||||
|
FT_Error error = FT_Err_Ok;
|
||||||
|
/* We are reallocating memory for `dst', so its pointer may change. */
|
||||||
|
FT_Byte* dst = *dst_bytes;
|
||||||
|
|
||||||
|
/* Check if we are within limits. */
|
||||||
|
if( ( *offset + size ) > WOFF2_DEFAULT_MAX_SIZE )
|
||||||
|
return FT_THROW( Array_Too_Large );
|
||||||
|
|
||||||
|
/* DEBUG - Remove later */
|
||||||
|
FT_TRACE2(( "Reallocating %lu to %lu.\n", *offset, (*offset + size) ));
|
||||||
|
/* Reallocate `dst'. */
|
||||||
|
if ( FT_REALLOC( dst,
|
||||||
|
(FT_ULong)(*offset),
|
||||||
|
(FT_ULong)(*offset + size ) ) )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
|
/* Copy data. */
|
||||||
|
ft_memcpy( dst + *offset, src, size );
|
||||||
|
|
||||||
|
*offset += size;
|
||||||
|
/* Set pointer of `dst' to its correct value. */
|
||||||
|
*dst_bytes = dst;
|
||||||
|
|
||||||
|
Exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static FT_Offset
|
static FT_Offset
|
||||||
CollectionHeaderSize( FT_ULong header_version,
|
CollectionHeaderSize( FT_ULong header_version,
|
||||||
FT_UShort num_fonts )
|
FT_UShort num_fonts )
|
||||||
|
@ -216,6 +253,32 @@
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FT_Long
|
||||||
|
compute_ULong_sum( FT_Byte* buf,
|
||||||
|
FT_ULong size )
|
||||||
|
{
|
||||||
|
FT_ULong checksum = 0;
|
||||||
|
FT_ULong aligned_size = size & ~3;
|
||||||
|
FT_ULong i;
|
||||||
|
FT_ULong v;
|
||||||
|
|
||||||
|
for( i = 0; i < aligned_size; i += 4 )
|
||||||
|
{
|
||||||
|
checksum += ( buf[i] << 24 ) | ( buf[i+1] << 16 ) |
|
||||||
|
( buf[i+2] << 8 ) | ( buf[i+3] << 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If size is not aligned to 4, treat as if it is padded with 0s */
|
||||||
|
if( size != aligned_size )
|
||||||
|
{
|
||||||
|
v = 0;
|
||||||
|
for( i = aligned_size ; i < size; ++i )
|
||||||
|
v |= buf[i] << ( 24 - 8 * ( i & 3 ) );
|
||||||
|
checksum += v;
|
||||||
|
}
|
||||||
|
return checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static FT_Error
|
static FT_Error
|
||||||
woff2_uncompress( FT_Byte* dst,
|
woff2_uncompress( FT_Byte* dst,
|
||||||
|
@ -293,15 +356,17 @@
|
||||||
FT_ULong transformed_buf_size,
|
FT_ULong transformed_buf_size,
|
||||||
WOFF2_Table* indices,
|
WOFF2_Table* indices,
|
||||||
WOFF2_Header woff2,
|
WOFF2_Header woff2,
|
||||||
FT_Byte* sfnt,
|
FT_Byte** sfnt_bytes,
|
||||||
FT_Memory memory )
|
FT_Memory memory )
|
||||||
{
|
{
|
||||||
FT_Error error = FT_Err_Ok;
|
FT_Error error = FT_Err_Ok;
|
||||||
FT_Stream stream = NULL;
|
FT_Stream stream = NULL;
|
||||||
|
FT_Byte* buf_cursor = NULL;
|
||||||
|
/* We are reallocating memory for `sfnt', so its pointer may change. */
|
||||||
|
FT_Byte* sfnt = *sfnt_bytes;
|
||||||
|
|
||||||
/* We're writing only one face per call, so initial offset is fixed. */
|
|
||||||
FT_ULong dst_offset = 12;
|
|
||||||
FT_UShort num_tables = woff2->num_tables;
|
FT_UShort num_tables = woff2->num_tables;
|
||||||
|
FT_ULong dest_offset = 12 + num_tables * 16UL;
|
||||||
|
|
||||||
FT_ULong checksum = 0;
|
FT_ULong checksum = 0;
|
||||||
FT_ULong loca_checksum = 0;
|
FT_ULong loca_checksum = 0;
|
||||||
|
@ -333,7 +398,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FT_UNUSED( dst_offset );
|
|
||||||
FT_UNUSED( loca_checksum );
|
FT_UNUSED( loca_checksum );
|
||||||
FT_UNUSED( checksum );
|
FT_UNUSED( checksum );
|
||||||
|
|
||||||
|
@ -351,12 +415,14 @@
|
||||||
WOFF2_TableRec table = *( indices[nn] );
|
WOFF2_TableRec table = *( indices[nn] );
|
||||||
|
|
||||||
/* DEBUG - Remove later */
|
/* DEBUG - Remove later */
|
||||||
FT_TRACE2(( "Seeking to %d with table size %d.\n", table.src_offset, table.src_length ));
|
FT_TRACE2(( "Seeking to %d with table size %d.\n",
|
||||||
|
table.src_offset, table.src_length ));
|
||||||
FT_TRACE2(( "Table tag: %c%c%c%c.\n",
|
FT_TRACE2(( "Table tag: %c%c%c%c.\n",
|
||||||
(FT_Char)( table.Tag >> 24 ),
|
(FT_Char)( table.Tag >> 24 ),
|
||||||
(FT_Char)( table.Tag >> 16 ),
|
(FT_Char)( table.Tag >> 16 ),
|
||||||
(FT_Char)( table.Tag >> 8 ),
|
(FT_Char)( table.Tag >> 8 ),
|
||||||
(FT_Char)( table.Tag ) ));
|
(FT_Char)( table.Tag ) ));
|
||||||
|
|
||||||
if ( FT_STREAM_SEEK( table.src_offset ) )
|
if ( FT_STREAM_SEEK( table.src_offset ) )
|
||||||
return FT_THROW( Invalid_Table );
|
return FT_THROW( Invalid_Table );
|
||||||
|
|
||||||
|
@ -370,6 +436,7 @@
|
||||||
return FT_THROW( Invalid_Table );
|
return FT_THROW( Invalid_Table );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checksum = 0;
|
||||||
if( ( table.flags & WOFF2_FLAGS_TRANSFORM ) != WOFF2_FLAGS_TRANSFORM )
|
if( ( table.flags & WOFF2_FLAGS_TRANSFORM ) != WOFF2_FLAGS_TRANSFORM )
|
||||||
{
|
{
|
||||||
/* Check if `head' is atleast 12 bytes. */
|
/* Check if `head' is atleast 12 bytes. */
|
||||||
|
@ -377,12 +444,30 @@
|
||||||
{
|
{
|
||||||
if( table.src_length < 12 )
|
if( table.src_length < 12 )
|
||||||
return FT_THROW( Invalid_Table );
|
return FT_THROW( Invalid_Table );
|
||||||
|
buf_cursor = transformed_buf + table.src_offset + 8;
|
||||||
|
WRITE_ULONG( buf_cursor, 0 );
|
||||||
}
|
}
|
||||||
|
table.dst_offset = dest_offset;
|
||||||
|
checksum = compute_ULong_sum( transformed_buf + table.src_offset,
|
||||||
|
table.src_length );
|
||||||
|
/* DEBUG - Remove later */
|
||||||
|
FT_TRACE2(( "Checksum = %u\n", checksum ));
|
||||||
|
|
||||||
|
if( WRITE_SFNT_BUF( transformed_buf + table.src_offset,
|
||||||
|
table.src_length ) )
|
||||||
|
return FT_THROW( Invalid_Table );
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
/* DEBUG - Remove later */
|
||||||
|
FT_TRACE2(( "This table has xform.\n" ));
|
||||||
|
|
||||||
|
/* TODO reconstruct transformed font tables! */
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO reconstruct the font tables! */
|
/* Set pointer of sfnt stream to its correct value. */
|
||||||
|
*sfnt_bytes = sfnt;
|
||||||
return FT_Err_Ok;
|
return FT_Err_Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -793,7 +878,7 @@
|
||||||
|
|
||||||
/* TODO Write table entries. */
|
/* TODO Write table entries. */
|
||||||
reconstruct_font( uncompressed_buf, woff2.uncompressed_size,
|
reconstruct_font( uncompressed_buf, woff2.uncompressed_size,
|
||||||
indices, &woff2, sfnt, memory );
|
indices, &woff2, &sfnt, memory );
|
||||||
|
|
||||||
error = FT_THROW( Unimplemented_Feature );
|
error = FT_THROW( Unimplemented_Feature );
|
||||||
/* DEBUG - Remove later */
|
/* DEBUG - Remove later */
|
||||||
|
@ -821,6 +906,7 @@
|
||||||
#undef ROUND4
|
#undef ROUND4
|
||||||
#undef WRITE_USHORT
|
#undef WRITE_USHORT
|
||||||
#undef WRITE_ULONG
|
#undef WRITE_ULONG
|
||||||
|
#undef WRITE_SFNT_BUF
|
||||||
|
|
||||||
|
|
||||||
/* END */
|
/* END */
|
||||||
|
|
|
@ -33,6 +33,9 @@ FT_BEGIN_HEADER
|
||||||
#define WOFF2_SFNT_HEADER_SIZE 12
|
#define WOFF2_SFNT_HEADER_SIZE 12
|
||||||
#define WOFF2_SFNT_ENTRY_SIZE 16
|
#define WOFF2_SFNT_ENTRY_SIZE 16
|
||||||
|
|
||||||
|
/* Suggested max size for output. */
|
||||||
|
#define WOFF2_DEFAULT_MAX_SIZE 30 * 1024 * 1024
|
||||||
|
|
||||||
FT_LOCAL( FT_ULong )
|
FT_LOCAL( FT_ULong )
|
||||||
woff2_known_tags( FT_Byte index );
|
woff2_known_tags( FT_Byte index );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue