summaryrefslogtreecommitdiff
path: root/utils/psdinfo
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/psdinfo
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'utils/psdinfo')
-rw-r--r--utils/psdinfo/psdinfo.cpp276
-rw-r--r--utils/psdinfo/psdinfo.vpc36
2 files changed, 312 insertions, 0 deletions
diff --git a/utils/psdinfo/psdinfo.cpp b/utils/psdinfo/psdinfo.cpp
new file mode 100644
index 0000000..7fe8bdb
--- /dev/null
+++ b/utils/psdinfo/psdinfo.cpp
@@ -0,0 +1,276 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Access to PSD image resources.
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "tier0/platform.h"
+#include "tier1/utlbuffer.h"
+
+#include "bitmap/imageformat.h"
+#include "bitmap/psd.h"
+
+int Usage()
+{
+ printf( "psdinfo ver. " __DATE__ " " __TIME__ "\n" );
+ printf( "Usage: \n" );
+ printf( " psdinfo [OPTIONS] psdfile.psd \n" );
+ printf( "Options: \n" );
+ printf( " -read read and print the info record (default) \n" );
+ printf( " -write update the info record with data from pipe \n" );
+ printf( "psdfile.psd the PSD file to process. \n" );
+ printf( "\n" );
+
+ return 1;
+}
+
+// Global options
+static struct Options {
+ Options() :
+ szFilename( "" ),
+ bWriteInfo( false )
+ {}
+
+ char const *szFilename;
+ bool bWriteInfo;
+} s_opts;
+
+
+// Map a file into a UtlBuffer
+bool LoadFileAndClose( FILE *fp, CUtlBuffer &buf, int numExtraBytesAlloc = 0 )
+{
+ if (!fp)
+ return false;
+
+ fseek( fp, 0, SEEK_END );
+ int nFileLength = ftell( fp );
+ fseek( fp, 0, SEEK_SET );
+
+ buf.EnsureCapacity( nFileLength + numExtraBytesAlloc );
+ int nBytesRead = fread( buf.Base(), 1, nFileLength, fp );
+
+ fclose( fp );
+
+ buf.SeekPut( CUtlBuffer::SEEK_HEAD, nBytesRead );
+
+ return true;
+}
+
+
+// Reading the info
+int ReadInfo()
+{
+ CUtlBuffer bufFile;
+ if ( !LoadFileAndClose( fopen( s_opts.szFilename, "rb" ), bufFile ) )
+ Error( "%s cannot be opened for read!\n", s_opts.szFilename );
+
+ if ( !IsPSDFile( bufFile ) )
+ Error( "%s is not a valid PSD file!\n", s_opts.szFilename );
+
+ PSDImageResources imgres = PSDGetImageResources( bufFile );
+ PSDResFileInfo resFileInfo( imgres.FindElement( PSDImageResources::eResFileInfo ) );
+ PSDResFileInfo::ResFileInfoElement descr = resFileInfo.FindElement( PSDResFileInfo::eDescription );
+ if ( descr.m_pvData )
+ {
+ unsigned char const *pvData = descr.m_pvData, *pvEnd = pvData + descr.m_numBytes;
+ while ( unsigned char const *pvCR = ( unsigned char const * ) memchr( pvData, '\r', pvEnd - pvData ) )
+ {
+ printf( "%.*s\n", pvCR - pvData, pvData );
+ pvData = pvCR + 1;
+ }
+ (pvEnd > pvData) ? printf( "%.*s\n", pvEnd - pvData, pvData ) : 0;
+ }
+
+ return 0;
+}
+
+
+struct Wr_PSDImageResources : public PSDImageResources {
+ friend int WriteInfo();
+ Wr_PSDImageResources( PSDImageResources const &x ) : PSDImageResources( x ) { }
+};
+struct Wr_PSDResFileInfo : public PSDResFileInfo {
+ friend int WriteInfo();
+ Wr_PSDResFileInfo( PSDResFileInfo const &x ) : PSDResFileInfo( x ) { }
+};
+
+void BufferMove( void const *pvDst, void const *pvSrc, size_t numBytes )
+{
+ memmove( const_cast< void * >( pvDst ), pvSrc, numBytes );
+}
+
+// Writing the info
+int WriteInfo()
+{
+ // We will have to:
+ // a) patch the "numBytesImgResource",
+ // b) probably insert our own section eResFileInfo
+ // c) inside the section add eDescription
+
+ int numDeltaBytes = 0;
+ CUtlBuffer inBuf;
+ while ( !feof( stdin ) )
+ {
+ char chBuffer[4096];
+ if ( !fgets( chBuffer, sizeof( chBuffer ) - 1, stdin ) )
+ break;
+ chBuffer[ sizeof( chBuffer ) - 1 ] = 0;
+ int len = strlen( chBuffer );
+ if ( len && chBuffer[ len - 1 ] == '\n' )
+ chBuffer[ len - 1 ] = '\r';
+ inBuf.Put( chBuffer, len );
+ }
+
+ if ( inBuf.TellPut() &&
+ '\r' == ( ( unsigned char const * ) inBuf.Base() )[ inBuf.TellPut() - 1 ] )
+ inBuf.SeekPut( CUtlBuffer::SEEK_CURRENT, -1 );
+
+ // Now once we have the info load up the PSD file
+ CUtlBuffer bufFile;
+ if ( !LoadFileAndClose( fopen( s_opts.szFilename, "rb" ), bufFile,
+ inBuf.TellPut() + 0x100 ) ) // Having extra room for insertions
+ Error( "%s cannot be opened for read!\n", s_opts.szFilename );
+ unsigned char const *pvBufBase = ( unsigned char const * ) bufFile.Base();
+
+ if ( !IsPSDFile( bufFile ) )
+ Error( "%s is not a valid PSD file!\n", s_opts.szFilename );
+
+ Wr_PSDImageResources imgres( PSDGetImageResources( bufFile ) );
+ if ( !imgres.m_pvBuffer )
+ Error( "%s does not have image resources to write!\n", s_opts.szFilename );
+
+ Wr_PSDResFileInfo resFileInfo( PSDResFileInfo( imgres.FindElement( PSDImageResources::eResFileInfo ) ) );
+
+ // Maybe the file info is missing?
+ if ( !resFileInfo.m_res.m_pvData )
+ {
+ // Insert a standard file info
+ unsigned char chStdFileInfo[] = { 0x38,0x42,0x49,0x4D, 0x04,0x04, 0,0,0,0, 0x00,0x07, 0x1C,0x02,0x00, 0x00,0x02, 0x00,0x02, 0 };
+ unsigned int addSize = sizeof( chStdFileInfo );
+
+ imgres.m_numBytes += addSize;
+ ( ( unsigned int * ) imgres.m_pvBuffer )[ -1 ] = BigLong( imgres.m_numBytes );
+
+ BufferMove( imgres.m_pvBuffer + addSize, imgres.m_pvBuffer, pvBufBase + bufFile.TellPut() - imgres.m_pvBuffer );
+ BufferMove( imgres.m_pvBuffer, chStdFileInfo, addSize );
+
+ resFileInfo.m_res.m_eType = PSDImageResources::eResFileInfo;
+ resFileInfo.m_res.m_numBytes = 7;
+ resFileInfo.m_res.m_pvData = imgres.m_pvBuffer + 12;
+
+ bufFile.SeekPut( CUtlBuffer::SEEK_CURRENT, addSize );
+ }
+
+ PSDResFileInfo::ResFileInfoElement descr = resFileInfo.FindElement( PSDResFileInfo::eDescription );
+
+ // If the description is present
+ if ( descr.m_pvData )
+ {
+ // Fix the buffer
+ numDeltaBytes = inBuf.TellPut() - descr.m_numBytes;
+ if ( numDeltaBytes )
+ BufferMove( descr.m_pvData + inBuf.TellPut(), descr.m_pvData + descr.m_numBytes, pvBufBase + bufFile.TellPut() - descr.m_pvData - descr.m_numBytes );
+
+ // Copy into the buffer
+ BufferMove( descr.m_pvData, inBuf.Base(), inBuf.TellPut() );
+ descr.m_numBytes += numDeltaBytes;
+ ( ( unsigned short * ) descr.m_pvData )[ -1 ] = BigShort( descr.m_numBytes );
+ }
+ else
+ {
+ // Need to insert the description
+ numDeltaBytes = 5 + inBuf.TellPut();
+ unsigned char const *pvInsertPoint = resFileInfo.m_res.m_pvData + resFileInfo.m_res.m_numBytes;
+ BufferMove( pvInsertPoint + numDeltaBytes, pvInsertPoint, pvBufBase + bufFile.TellPut() - pvInsertPoint );
+
+ // Copy into the buffer
+ unsigned char signature[] = { 0x1C,0x02, PSDResFileInfo::eDescription };
+ BufferMove( pvInsertPoint, signature, sizeof( signature ) );
+
+ unsigned short usDescrBytes = inBuf.TellPut();
+ * ( unsigned short * ) ( pvInsertPoint + 3 ) = BigShort( usDescrBytes );
+
+ BufferMove( pvInsertPoint + 5, inBuf.Base(), inBuf.TellPut() );
+ }
+
+ // File size changed
+ bufFile.SeekPut( CUtlBuffer::SEEK_CURRENT, numDeltaBytes );
+
+ // Still remaining to fix: the file-info size and imgres size
+
+ // File-info
+ resFileInfo.m_res.m_numBytes += numDeltaBytes;
+ if ( numDeltaBytes & 1 ) // Odd number of bytes delta
+ {
+ if ( resFileInfo.m_res.m_numBytes & 1 ) // It was even, becomes odd
+ {
+ ++ numDeltaBytes;
+ BufferMove( resFileInfo.m_res.m_pvData + resFileInfo.m_res.m_numBytes + 1, resFileInfo.m_res.m_pvData + resFileInfo.m_res.m_numBytes, pvBufBase + bufFile.TellPut() - resFileInfo.m_res.m_pvData - resFileInfo.m_res.m_numBytes );
+ const_cast< unsigned char & > ( resFileInfo.m_res.m_pvData[ resFileInfo.m_res.m_numBytes ] ) = 0x00;
+ bufFile.SeekPut( CUtlBuffer::SEEK_CURRENT, +1 );
+ }
+ else // It was odd, becomes even
+ {
+ -- numDeltaBytes;
+ BufferMove( resFileInfo.m_res.m_pvData + resFileInfo.m_res.m_numBytes, resFileInfo.m_res.m_pvData + resFileInfo.m_res.m_numBytes + 1, pvBufBase + bufFile.TellPut() - resFileInfo.m_res.m_pvData - resFileInfo.m_res.m_numBytes - 1 );
+ bufFile.SeekPut( CUtlBuffer::SEEK_CURRENT, -1 );
+ }
+ }
+
+ ( ( unsigned short * ) resFileInfo.m_res.m_pvData )[ -1 ] = BigShort( resFileInfo.m_res.m_numBytes );
+
+ // Image resources
+ imgres.m_numBytes += numDeltaBytes;
+ ( ( unsigned int * ) imgres.m_pvBuffer )[ -1 ] = BigLong( imgres.m_numBytes );
+
+ // Now write the file buffer
+ {
+ FILE *fp = fopen( s_opts.szFilename, "wb" );
+ if ( !fp )
+ Error( "%s cannot be opened for update!\n", s_opts.szFilename );
+
+ fwrite( bufFile.Base(), 1, bufFile.TellPut(), fp );
+ fclose( fp );
+ }
+
+ return 0;
+}
+
+
+// Application entry point
+int main( int argc, char **argv )
+{
+ // Filename is the last argument
+ if ( argc <= 1 )
+ return Usage();
+ else
+ s_opts.szFilename = argv[argc - 1];
+
+ // Read out all the options
+ for ( int iArg = 1; iArg < argc - 1; ++ iArg )
+ {
+ if ( !stricmp( argv[iArg], "-read" ) )
+ {
+ s_opts.bWriteInfo = false;
+ }
+ else if ( !stricmp( argv[iArg], "-write" ) )
+ {
+ s_opts.bWriteInfo = true;
+ }
+ else
+ {
+ printf( "Unknown option \"%s\"!\n", argv[iArg] );
+ return Usage();
+ }
+ }
+
+ // Go ahead and perform the corresponding read or write
+ return s_opts.bWriteInfo ? WriteInfo() : ReadInfo();
+}
+
diff --git a/utils/psdinfo/psdinfo.vpc b/utils/psdinfo/psdinfo.vpc
new file mode 100644
index 0000000..21cc872
--- /dev/null
+++ b/utils/psdinfo/psdinfo.vpc
@@ -0,0 +1,36 @@
+//-----------------------------------------------------------------------------
+// PsdInfo.VPC
+//
+// Project Script
+//-----------------------------------------------------------------------------
+
+$Macro SRCDIR "..\.."
+$Macro OUTBINDIR "$SRCDIR\..\game\bin"
+
+$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
+
+$Configuration
+{
+ $Compiler
+ {
+ $AdditionalIncludeDirectories "$BASE;$(DevEnvDir)..\..\vc\vcpackages;$(DevEnvDir)..\..\..\Common Files\Microsoft Shared\MSEnv"
+ }
+}
+
+$Project "psdinfo"
+{
+ $Folder "Source Files"
+ {
+ $File "psdinfo.cpp"
+ }
+
+ $Folder "Header Files"
+ {
+ }
+
+ $Folder "Link Libraries"
+ {
+ $Lib bitmap
+ $Lib tier2
+ }
+}