Commits

Andreas Tscharner committed 5df526e

Implemented new option to prepare the data for linking

* New option -m
* Data will be converted to ELF obj file, ready for linking
* Added example for embedded/directly linked

Comments (0)

Files changed (5)

src/StatusCodes.hxx

 //      StatusCodes.hxx
 //
-//      Copyright 2011 Andreas Tscharner <andy@vis.ethz.ch>
+//      Copyright 2011, 2014 Andreas Tscharner <andy@vis.ethz.ch>
 //
 //      This program is free software; you can redistribute it and/or modify
 //      it under the terms of the GNU Lesser General Public License as
  * these codes
  *
  * \author Andreas Tscharner
- * \date 2011-09-04
+ * \date 2014-08-10
  */
 
 
 #define ERROR_ENCRYPTION_ENCRYPT            ERROR_BASE-24  //!< An error occurred while encrypting
 #define ERROR_ENCRYPTION_DECRYPT            ERROR_BASE-25  //!< An error occurred while decrypting
 
+// Errors while creating an efl file from rdf (for directly linked data)
+#define ERROR_UNKNOWN_ARCH                  ERROR_BASE-40  //!< The architecture is unknown
+
 // General errors
 #define ERROR_INVALID_PARAMETER        ERROR_BASE-100      //!< The provided parameter was illegal
 #define ERROR_NOT_ENOUGH_MEMORY        ERROR_BASE-101      //!< Not enough memory available for this action

src/compiler/lrc.cxx

 //      lrc.cxx
 //
-//      Copyright 2011-2013 Andreas Tscharner <andy@vis.ethz.ch>
+//      Copyright 2011-2014 Andreas Tscharner <andy@vis.ethz.ch>
 //
 //      This program is free software; you can redistribute it and/or modify
 //      it under the terms of the GNU Lesser General Public License as
  * and then the collector which creates the .rdf file
  *
  * \author Andreas Tscharner
- * \date 2013-09-08
+ * \date 2014-08-22
  */
 
 
 #include "include/EncryptDecrypt.hxx"
 #include "../lrcExceptions.hxx"
 #include "../Utils.hxx"
+#include "../StatusCodes.hxx"
 #include "InFileParser.hxx"
 #include "Collector.hxx"
 #include "ParserFactory.hxx"
 {
 	std::cout << "lrc - Linux Resource Compiler\n";
 	std::cout << "A resource compiler for Linux (Version " << VERSION << ")\n\n";
-	std::cout << "Usage:\n" << argv[0] << " [-d] [-o <rdfFile>] [-c <compression type>] [-e <encryption type> -p <password>] <RCFile>|<RIFFile>\n";
+	std::cout << "Usage:\n" << argv[0] << " [-d] [-m] [-o <rdfFile>] [-c <compression type>] [-e <encryption type> -p <password>] <RCFile>|<RIFFile>\n";
 	std::cout << "\t-h\t\t\tShow this help screen\n";
 	std::cout << "\t-d\t\t\tDeny overwriting (optional)\n";
+	std::cout << "\t-m\t\t\tPrepare data for embedding into final file\n";
 	std::cout << "\t-o <rdfFile>\t\tDefine final resource data file (optional)\n";
 	std::cout << "\t-c <compression type>\tDefine compression type for the whole file\n";
 	std::cout << "\t-e <encryption type>\tDefine encryption type for the whole file\n";
 	std::cout << "\t-p <password>\t\tPassword when encryption is used (ignored otherwise)\n";
 	std::cout << "\t<RCFile>\t\tInput file in RC format\n";
-	std::cout << "\t<RCFile>\t\tInput file in RIF format (XML format)\n";
+	std::cout << "\t<RIFFile>\t\tInput file in RIF format (XML format)\n";
+}
+
+//! Convert data to ELF binary format
+int convert_to_elf(const char *p_rdfFilename, const char *p_elfFilename)
+{
+	std::string outTarget;
+	std::string execCmd;
+	int execRet;
+
+#ifdef __x86_64__
+	outTarget = "elf64-x86-64";
+#endif
+#ifdef __i386__
+	outTarget = "elf32-i386";
+#endif
+
+
+	if (outTarget.empty()) {
+		return ERROR_UNKNOWN_ARCH;
+	};
+
+	execCmd = "objcopy -I binary -O " + outTarget + " -B i386 ";
+	execCmd += const_cast<const char *>(p_rdfFilename);
+	execCmd += " ";
+	execCmd += const_cast<const char *>(p_elfFilename);
+
+	DEBUG_PRINT(("Execution string: %s\n", execCmd.c_str()))
+	execRet = std::system(execCmd.c_str());
+
+	return execRet;
 }
 
 
 	char *errMsg;
 	char *inputFile = nullptr;
 	char *rdfFile = nullptr;
+	char *elfFile = nullptr;
 	char *compressType = nullptr;
 	char *encryptType = nullptr;
 	char *pwdStr = nullptr;
 	unsigned char *password = nullptr;
 	bool allowOverwrite = true;
+	bool embeddedData = false;
 	lrc::CompressionType complCompress = lrc::NoneCompression;
 	lrc::EncryptionType complEncrypt = lrc::NoneEncryption;
 
 		return -1;
 	};
 
-	while ((optRet = getopt(argc, argv, "dho:c:e:p:")) != -1) {
+	while ((optRet = getopt(argc, argv, "hdmo:c:e:p:")) != -1) {
 		switch (optRet) {
 			case 'o' :
 				rdfFile = new char[strlen(optarg)+1];
 				DEBUG_PRINT(("Output file: %s\n", rdfFile))
 				break;
 
+			case 'm' :
+				embeddedData = true;
+				DEBUG_PRINT(("Prepare for embedded data\n"))
+				break;
+
 			case 'c' :
 				compressType = new char[strlen(optarg)+1];
 				memset(compressType, 0, (strlen(optarg)+1));
 	strncpy(inputFile, argv[optind], (strlen(argv[optind])));
 
 	if (!rdfFile) {
-		rdfFile = replace_extension(inputFile, (char *)".rdf");
+		rdfFile = replace_extension(inputFile, ".rdf");
 	};
 	DEBUG_PRINT(("Input file: %s; rdfFile: %s\n", inputFile, rdfFile))
 
 		delete[] password;
 	};
 
+	if (embeddedData) {
+		elfFile = replace_extension(rdfFile, ".o");
+		errVal = convert_to_elf(rdfFile, elfFile);
+		if (errVal < 0) {
+			std::cout << "Converting to ELF file format failed with code " << errVal << "\n";
+			return -1;
+		};
+		std::cout << "Please add " << elfFile << " to the list of files for linking\n";
+		delete[] elfFile;
+	};
+
 	delete inputDataCollector;
 	delete inputFileParser;
 

src/example/EmbeddedLogos.rc

+#
+# Example .rc file for Linux Resource Compiler
+
+#
+# Resource ID		Resource File				Compression	Encryption
+FREEBSD-LOGO		"data/freebsd-devil.png"	zLib		None
+APPLE-LOGO			"data/apple.png"			None		None
+WINDOWS-LOGO		"data/Windows Logo.png"		bzip2		None
+LINUX-LOGO			"data/tux.png"				bzip2		Serpent     "MySecretPassword"

src/example/Makefile.am

 #      Makefile.am
 #
-#      Copyright 2011, 2012 Andreas Tscharner <andy@vis.ethz.ch>
+#      Copyright 2011, 2012, 2014 Andreas Tscharner <andy@vis.ethz.ch>
 #
 #      This program is free software; you can redistribute it and/or modify
 #      it under the terms of the GNU Lesser General Public License as
 #
 # Define all programs
 if HAVE_ALL_SDL
-bin_PROGRAMS = ListResources ShowImage ExtractText
+bin_PROGRAMS = ListResources ShowImage ShowEmbeddedImage ExtractText
 else
 bin_PROGRAMS = ListResources ExtractText
 endif
 ListResources_SOURCES = ListResources.cxx
 if HAVE_ALL_SDL
 ShowImage_SOURCES = ShowImage.cxx
+ShowEmbeddedImage_SOURCES = ShowEmbeddedImage.cxx
 endif
 ExtractText_SOURCES = ExtractText.cxx
 
 if HAVE_ALL_SDL
 ShowImage_LDADD = -llrc -lSDL -lSDL_image
 ShowImage_LDFLAGS = -L../lib/.libs -export-dynamic
+ShowEmbeddedImage_LDADD = EmbeddedLogos.o -llrc -lSDL -lSDL_image
+ShowEmbeddedImage_LDFLAGS = -L../lib/.libs -export-dynamic
 endif
 ExtractText_LDADD = -llrc
 ExtractText_LDFLAGS = -L../lib/.libs -export-dynamic
 # Define data for programs
 if HAVE_ALL_SDL
 ShowImage_DEPENDENCIES = OSLogos.rdf
+ShowEmbeddedImage_DEPENDENCIES = EmbeddedLogos.o
 if !NO_ENCRYPTION
 ShowImage_DEPENDENCIES += logos.rdf
 ExtractText_LRC_OPTS = -e Serpent -p @Password
 
 #
 # Add all data into package
-EXTRA_DIST = RIFExample.sh logos.rc texts.rc OSLogos.rif Password.txt Password data
+EXTRA_DIST = RIFExample.sh logos.rc texts.rc OSLogos.rif EmbeddedLogos.rc \
+             Password.txt Password data
 
 #
 # Create text.rdf files from text.rc
 	../compiler/lrc texts.rc -c bzip2 $(ExtractText_LRC_OPTS)
 
 #
+# Create also the ELF file for the embedded example
+EmbeddedLogos.o: EmbeddedLogos.rc
+	../compiler/lrc -m EmbeddedLogos.rc
+
+#
 # Create rdf files from RC files
 .rc.rdf:
 	../compiler/lrc $<
 # Use own clean target
 clean-local:
 	-rm -f *.rdf
-	-rm -f README.txt Resource.txt ResourceMgr.txt
+	-rm -f README.txt Resource.txt ResourceMgr.txt EmbeddedLogos.o

src/example/ShowEmbeddedImage.cxx

+//      ShowEmbeddedImage.cxx
+//
+//      Copyright 2014 Andreas Tscharner <andy@vis.ethz.ch>
+//
+//      This program is free software; you can redistribute it and/or modify
+//      it under the terms of the GNU Lesser General Public License as
+//      published by the Free Software Foundation; either version 3 of the
+//      License, or (at your option) any later version.
+//
+//      This program is distributed in the hope that it will be useful,
+//      but WITHOUT ANY WARRANTY; without even the implied warranty of
+//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//      GNU General Public License for more details.
+//
+//      You should have received a copy of the GNU Lesser General Public
+//      License along with this program; if not, write to the Free Software
+//      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+//      MA 02110-1301, USA.
+
+
+#include <iostream>
+#include <SDL/SDL.h>
+#include <SDL/SDL_image.h>
+#include "../include/ResourceManager.hxx"
+
+extern "C" {
+	extern unsigned char _binary_EmbeddedLogos_rdf_start;
+	extern unsigned char _binary_EmbeddedLogos_rdf_end;
+};
+
+using namespace lrc;
+
+void deleteList(char **p_dataList, int p_dataSize)
+{
+	for (int i = (p_dataSize-1); i>=0; i--)
+		delete[] p_dataList[i];
+	delete[] p_dataList;
+}
+
+int main(int argc, char **argv)
+{
+	const int WINDOW_WIDTH = 640;
+	const int WINDOW_HEIGHT = 480;
+
+	ResourceManager *logos;
+	Resource *logoRes;
+	lrc::CompressionType comprType;
+	char **logosList;
+	int numLogos;
+	SDL_Surface *mainScreen, *logoSurf;
+	SDL_RWops *logoImg;
+	SDL_Rect logoWin;
+
+
+	logos = new ResourceManager(
+	  &_binary_EmbeddedLogos_rdf_start,
+	  &_binary_EmbeddedLogos_rdf_end,
+	  lrc::NoneCompression,
+	  lrc::NoneEncryption,
+	  nullptr);
+
+	logosList = logos->get_resource_ids(numLogos);
+	if (numLogos < 1) {
+		std::cout << "No entries found" << std::endl;
+		delete logos;
+		return -1;
+	};
+
+	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
+		std::cout << "Could not initialize SDL: ";
+		std::cout << SDL_GetError() << std::endl;
+		deleteList(logosList, numLogos);
+		delete logos;
+		return -1;
+	};
+
+	mainScreen = SDL_SetVideoMode(WINDOW_WIDTH, WINDOW_HEIGHT, 0, SDL_HWPALETTE|SDL_DOUBLEBUF);
+	if (mainScreen == NULL) {
+		std::cout << "Could not set windowed video mode to " << WINDOW_WIDTH << "x" << WINDOW_HEIGHT << ": ";
+		std::cout << SDL_GetError() << std::endl;
+		deleteList(logosList, numLogos);
+		delete logos;
+		return -1;
+	};
+	SDL_WM_SetCaption("Embedded example", NULL);
+
+	for (int i=0; i<numLogos; i++) {
+		if (i !=  (numLogos-1)) {
+			logoRes = logos->get_resource(logosList[i]);
+		} else {
+			logoRes = logos->get_resource(logosList[i], (const unsigned char *)"MySecretPassword");
+		};
+		logoImg = SDL_RWFromMem(logoRes->get_res_data(), logoRes->get_res_size());
+		logoSurf = IMG_LoadPNG_RW(logoImg);
+		SDL_FreeRW(logoImg);
+
+		logoWin.x = (WINDOW_WIDTH / 2) - (logoSurf->w / 2);
+		logoWin.y = (WINDOW_HEIGHT /2) - (logoSurf->h / 2);
+		logoWin.w = logoSurf->w;
+		logoWin.h = logoSurf->h;
+
+		SDL_BlitSurface(logoSurf, NULL, mainScreen, &logoWin);
+		SDL_Flip(mainScreen);
+
+		SDL_Delay(2000);
+
+		SDL_FreeSurface(logoSurf);
+
+		SDL_FillRect(mainScreen, &logoWin, 0);
+
+		delete logoRes;
+	};
+	delete logos;
+
+	SDL_Quit();
+
+	return 0;
+}
+