/* * Implementation of stdlib free. */ void free(void *ptr) { if (ptr == NULL) return; freePointer(startHeap, (uintptr_t) ptr); if (debugMalloc()) { printf("MALLOC: free(%p)\n",ptr); } }
/* * Finds the AU pointed to by ptr, and frees it. Attempts to expand with * neighboring free AU's. */ void freePointer(AllocUnit *current, uintptr_t ptr) { uintptr_t loc = (uintptr_t) current->memLoc; if (ptr < loc + current->size && ptr >= loc) { current->isFree = 1; /* check for neighboring free space and merge */ if (current->next != NULL && current->next->isFree) mergeAU(current); if (current->last != NULL && current->last->isFree) mergeAU(current->last); } else if (current->next != NULL) { freePointer(current->next, ptr); } else { return; /*couldnt find pointer just return cleanly */ } }
DatIndexCategory* ScanDatTask::categorize( ANetFileType p_fileType, const byte* p_data, size_t p_size ) { DatIndexCategory* category = nullptr; switch ( p_fileType ) { case ANFT_ATEX: case ANFT_ATTX: case ANFT_ATEC: case ANFT_ATEP: case ANFT_ATEU: case ANFT_ATET: case ANFT_DDS: case ANFT_JPEG: case ANFT_WEBP: MakeCategory( wxT( "Textures" ) ); switch ( p_fileType ) { case ANFT_ATEX: MakeSubCategory( wxT( "Generic Textures" ) ); break; case ANFT_ATTX: MakeSubCategory( wxT( "Terrain Textures" ) ); break; case ANFT_ATEC: MakeSubCategory( wxT( "ATEC" ) ); break; case ANFT_ATEP: MakeSubCategory( wxT( "Map Textures" ) ); break; case ANFT_ATEU: MakeSubCategory( wxT( "UI Textures" ) ); break; case ANFT_ATET: MakeSubCategory( wxT( "ATET" ) ); break; case ANFT_DDS: MakeSubCategory( wxT( "DDS" ) ); break; case ANFT_JPEG: MakeSubCategory( wxT( "JPEG" ) ); break; case ANFT_WEBP: MakeSubCategory( wxT( "WebP" ) ); break; } if ( ( p_fileType == ANFT_ATEX || p_fileType == ANFT_ATTX || p_fileType == ANFT_ATEC || p_fileType == ANFT_ATEP || p_fileType == ANFT_ATEU || p_fileType == ANFT_ATET ) ) { uint16 width = *reinterpret_cast<const uint16*>( p_data + 8 ); uint16 height = *reinterpret_cast<const uint16*>( p_data + 10 ); MakeSubCategory( wxString::Format( wxT( "%ux%u" ), width, height ) ); } else if ( p_fileType == ANFT_DDS && p_size >= 20 ) { uint32 width = *reinterpret_cast<const uint32*>( p_data + 16 ); uint32 height = *reinterpret_cast<const uint32*>( p_data + 12 ); MakeSubCategory( wxString::Format( wxT( "%ux%u" ), width, height ) ); } break; case ANFT_Sound: case ANFT_MP3: case ANFT_Ogg: case ANFT_PackedMP3: case ANFT_PackedOgg: case ANFT_asndMP3: case ANFT_asndOgg: MakeCategory( wxT( "Sounds" ) ); switch ( p_fileType ) { case ANFT_MP3: MakeSubCategory( wxT( "MP3" ) ); break; case ANFT_Ogg: MakeSubCategory( wxT( "Ogg" ) ); break; case ANFT_asndMP3: MakeSubCategory( wxT( "asndMP3" ) ); break; case ANFT_asndOgg: MakeSubCategory( wxT( "asndOgg" ) ); break; case ANFT_PackedMP3: MakeSubCategory( wxT( "PackedMP3" ) ); break; case ANFT_PackedOgg: MakeSubCategory( wxT( "PackedOgg" ) ); break; } break; case ANFT_Binary: case ANFT_EXE: case ANFT_DLL: MakeCategory( wxT( "Binaries" ) ); break; // when catagorize string files the process will slower, // due to strs file format that have to read near end of file to know what language is case ANFT_StringFile: { uint32 entryNumber = this->currentProgress( ); auto buffer = allocate<byte>( m_datFile.fileSize( entryNumber ) ); auto size = m_datFile.readFile( entryNumber, buffer ); gw2f::StringsFile stringFile( buffer, size ); MakeCategory( wxT( "Strings" ) ); switch ( stringFile.language( ) ) { case gw2f::language::English: MakeSubCategory( wxT( "English" ) ); break; case gw2f::language::French: MakeSubCategory( wxT( "French" ) ); break; case gw2f::language::German: MakeSubCategory( wxT( "German" ) ); break; case gw2f::language::Korean: MakeSubCategory( wxT( "Korean" ) ); break; case gw2f::language::Spanish: MakeSubCategory( wxT( "Spanish" ) ); break; } freePointer( buffer ); break; } case ANFT_Manifest: MakeCategory( wxT( "Manifests" ) ); break; case ANFT_PortalManifest: MakeCategory( wxT( "Portal Manifests" ) ); break; case ANFT_TextPackManifest: MakeCategory( wxT( "TextPack Manifests" ) ); break; case ANFT_TextPackVariant: MakeCategory( wxT( "TextPack Variant" ) ); break; case ANFT_TextPackVoices: MakeCategory( wxT( "TextPack Voices" ) ); break; case ANFT_Bank: MakeCategory( wxT( "Soundbank" ) ); break; case ANFT_BankIndex: MakeCategory( wxT( "Soundbank Index" ) ); break; case ANFT_AudioScript: MakeCategory( wxT( "Audio Scripts" ) ); break; case ANFT_Model: MakeCategory( wxT( "Models" ) ); break; case ANFT_DependencyTable: MakeCategory( wxT( "Dependency Tables" ) ); break; case ANFT_EULA: MakeCategory( wxT( "EULA" ) ); break; case ANFT_Cinematic: MakeCategory( wxT( "Cinematics" ) ); break; case ANFT_HavokCollision: MakeCategory( wxT( "Havok Collision" ) ); break; case ANFT_MapContent: MakeCategory( wxT( "Map Content" ) ); break; case ANFT_MapParam: MakeCategory( wxT( "Map Parameter" ) ); break; case ANFT_MapShadow: MakeCategory( wxT( "Map Shadow" ) ); break; case ANFT_PagedImageTable: MakeCategory( wxT( "Paged Image Table" ) ); break; case ANFT_Material: MakeCategory( wxT( "Materials" ) ); break; case ANFT_Composite: MakeCategory( wxT( "Composite Data" ) ); break; case ANFT_AnimSequences: MakeCategory( wxT( "Animation Sequences" ) ); break; case ANFT_EmoteAnimation: MakeCategory( wxT( "Emote Animations" ) ); break; case ANFT_FontFile: MakeCategory( wxT( "Font" ) ); break; case ANFT_Bink2Video: MakeCategory( wxT( "Bink Videos" ) ); break; case ANFT_ShaderCache: MakeCategory( wxT( "Shader Cache" ) ); break; case ANFT_Config: MakeCategory( wxT( "Configuration" ) ); break; case ANFT_PF: case ANFT_ARAP: MakeCategory( wxT( "Misc" ) ); if ( p_fileType == ANFT_PF && p_size >= 12 ) { MakeSubCategory( wxString( reinterpret_cast<const char*>( p_data + 8 ), 4 ) ); } break; default: // unknown stuff MakeCategory( wxT( "Unknown" ) ); // to do: printable character detection in files for detect text files. //MakeSubCategory( wxString::Format( wxT( "%x" ), *reinterpret_cast<const uint32*>( p_data ) ) ); break; } return category; }
void ImageControl::UpdateBitmap( ) { m_bitmap = wxBitmap( ); if ( m_image.IsOk( ) ) { m_bitmap.Create( m_image.GetWidth( ), m_image.GetHeight( ) ); wxMemoryDC dc( m_bitmap ); // New image so we don't mess with the actual image wxImage image( m_image ); bool imageHasAlpha = image.HasAlpha( ); // Skip backdrop if image has no alpha, or if it's not visible if ( imageHasAlpha && !!( m_channels & IC_Alpha ) ) { for ( uint y = 0; y < ( uint ) m_bitmap.GetHeight( ); y += m_backdrop.GetHeight( ) ) { for ( uint x = 0; x < ( uint ) m_bitmap.GetWidth( ); x += m_backdrop.GetWidth( ) ) { dc.DrawBitmap( m_backdrop, x, y ); } } } // Check if any channels have been toggled off if ( m_channels != IC_All ) { uint numPixels = image.GetWidth( ) * image.GetHeight( ); uint8* alphaCache = nullptr; // Any colors toggled off? if ( !( m_channels & IC_Red ) || !( m_channels & IC_Green ) || !( m_channels & IC_Blue ) ) { uint8* colors = allocate<uint8>( numPixels * 3 ); ::memcpy( colors, image.GetData( ), numPixels * 3 ); // Setting colors clears the alpha, so cache it for restoration later, // if the image has an alpha channel and it's visible if ( imageHasAlpha && ( m_channels & IC_Alpha ) ) { alphaCache = allocate<uint8>( numPixels ); ::memcpy( alphaCache, image.GetAlpha( ), numPixels ); } // If all colors are off, but alpha is on, alpha should be made white bool noColors = !( ( m_channels & IC_Red ) || ( m_channels & IC_Green ) || ( m_channels & IC_Blue ) ); bool whiteAlpha = noColors && !!( m_channels & IC_Alpha ); // Loop through the pixels for ( uint i = 0; i < numPixels; i++ ) { if ( whiteAlpha ) { if ( alphaCache ) { ::memset( &colors[i * 3], alphaCache[i], sizeof( uint8 ) * 3 ); } else { ::memset( &colors[i * 3], 0xff, sizeof( uint8 ) * 3 ); } } else { // Red turned off? if ( !( m_channels & IC_Red ) ) { colors[i * 3 + 0] = 0x00; } // Green turned off? if ( !( m_channels & IC_Green ) ) { colors[i * 3 + 1] = 0x00; } // Blue turned off? if ( !( m_channels & IC_Blue ) ) { colors[i * 3 + 2] = 0x00; } } } // If alpha should be white, it should not be alpha too if ( whiteAlpha ) { freePointer( alphaCache ); } // Update colors image.SetData( colors ); } // Was alpha turned off? if ( imageHasAlpha && !( m_channels & IC_Alpha ) ) { uint8* alpha = allocate<uint8>( numPixels ); ::memset( alpha, 0xff, numPixels ); image.SetAlpha( alpha ); } else if ( alphaCache ) { image.SetAlpha( alphaCache ); } } // Draw the image dc.DrawBitmap( wxBitmap( image ), 0, 0 ); } this->Refresh( ); }
bool ImageReader::readATEX( wxSize& po_size, BGR*& po_colors, uint8*& po_alphas ) const { Assert( isValidHeader( m_data.GetPointer( ), m_data.GetSize( ) ) ); auto atex = reinterpret_cast<const ANetAtexHeader*>( m_data.GetPointer( ) ); // Determine mipmap0 size and bail if the file is too small if ( m_data.GetSize( ) >= sizeof( ANetAtexHeader ) +sizeof( uint32 ) ) { auto mipMap0Size = *reinterpret_cast<const uint32*>( &m_data[sizeof( ANetAtexHeader )] ); if ( mipMap0Size + sizeof( ANetAtexHeader ) > m_data.GetSize( ) ) { po_size.Set( 0, 0 ); return false; } } else { po_size.Set( 0, 0 ); return false; } // Init some fields auto data = reinterpret_cast<const uint8_t*>( m_data.GetPointer( ) ); po_colors = nullptr; po_alphas = nullptr; uint16 width = atex->width; uint16 height = atex->height; // Hack for read 126x64 ATEX if ( width == 126 && height == 64 ) { width = 128; } // Allocate output auto output = allocate<BGRA>( width * height ); uint32_t outputBufferSize; // Uncompress switch ( atex->formatInteger ) { case FCC_DXT1: if ( gw2dt::compression::inflateTextureFileBuffer( m_data.GetSize( ), data, outputBufferSize, reinterpret_cast<uint8_t*>( output ) ) ) { this->processDXT1( output, width, height, po_colors, po_alphas ); } break; case FCC_DXT2: case FCC_DXT3: case FCC_DXTN: if ( gw2dt::compression::inflateTextureFileBuffer( m_data.GetSize( ), data, outputBufferSize, reinterpret_cast< uint8_t* >( output ) ) ) { this->processDXT3( output, width, height, po_colors, po_alphas ); } break; case FCC_DXT4: case FCC_DXT5: if ( gw2dt::compression::inflateTextureFileBuffer( m_data.GetSize( ), data, outputBufferSize, reinterpret_cast< uint8_t* >( output ) ) ) { this->processDXT5( output, width, height, po_colors, po_alphas ); } break; case FCC_DXTA: if ( gw2dt::compression::inflateTextureFileBuffer( m_data.GetSize( ), data, outputBufferSize, reinterpret_cast< uint8_t* >( output ) ) ) { this->processDXTA( reinterpret_cast< uint64* >( output ), width, height, po_colors ); } break; case FCC_DXTL: if ( gw2dt::compression::inflateTextureFileBuffer( m_data.GetSize( ), data, outputBufferSize, reinterpret_cast<uint8_t*>( output ) ) ) { this->processDXT5( output, width, height, po_colors, po_alphas ); for ( uint i = 0; i < ( static_cast<uint>( width ) * static_cast<uint>( height ) ); i++ ) { po_colors[i].r = ( po_colors[i].r * po_alphas[i] ) / 0xff; po_colors[i].g = ( po_colors[i].g * po_alphas[i] ) / 0xff; po_colors[i].b = ( po_colors[i].b * po_alphas[i] ) / 0xff; } } break; case FCC_3DCX: if ( gw2dt::compression::inflateTextureFileBuffer( m_data.GetSize( ), data, outputBufferSize, reinterpret_cast< uint8_t* >( output ) ) ) { this->process3DCX( reinterpret_cast<RGBA*>( output ), width, height, po_colors, po_alphas ); } break; default: freePointer( output ); return false; } freePointer( output ); if ( po_colors ) { po_size.Set( width, height ); return true; } return false; }