/* * ted2rtf - a very simple converter for extracting the text of an AMiga TED * file, to a format usuable in Word etc. * AT the moment it doesnt use any of the character formatting. * * TED files are in IFF text format * 'FORM' filesize 'FTXT' [ ChunkID ChunkSize CHunkData....... ]* * * Version: 1.0 * Author: John Donoghue * Copyright: John Donoghue, 2004. * Licence: GPL - see www.gnu.org for the current licence. */ /* History * 1.0 18-Jan-2004 Initial version */ //------------------------------------------------------------- #include #include //------------------------------------------------------------- class TEDConverter { public: TEDConverter(); virtual ~TEDConverter(); bool convert(std::istream & str, std::ostream & out); private: unsigned long readSize(std::istream & in); unsigned long readID(std::istream & in); unsigned long makeID(int * buff); bool onChunk(std::istream &in, std::ostream & out, unsigned long chunk, unsigned long size); // some of the main chunk types - only onCHRS is currently used bool onTCPP(std::istream &in, std::ostream & out, unsigned long sz); bool onTCPH(std::istream &in, std::ostream & out, unsigned long sz); bool onCHRS(std::istream &in, std::ostream & out, unsigned long sz); }; //------------------------------------------------------------- int main() { std::cerr << "TED2RTF - Amiga Text Edit file to Rich Text Format Converter\n"; std::cerr << "(c) John Donoghue, 2004.\n"; TEDConverter c; c.convert(std::cin, std::cout); return 0; } //------------------------------------------------------------- TEDConverter::TEDConverter() { } //------------------------------------------------------------- TEDConverter::~TEDConverter() { } //------------------------------------------------------------- bool TEDConverter::convert(std::istream & in, std::ostream & out) { // dump start of rtf char * start = "{\\rtf1\n" "\\ansi\\deff0\n" "{\\fonttbl\n" " {\\f0\\fmodern\\fprq1\\fcharset0 Courier New;}\n" " {\\f1\fswiss\\fcharset0 Arial;}\n" "}\n" "\\f0\\fs20\n"; out << start; // read firm unsigned long head = readID(in); int form[] = { 'F','O','R','M' }; if(head != makeID(form)) { std::cerr << "Error: not a IFF file - incorrect header.\n"; return false; } unsigned long size = readSize(in); // IFF file type head = readID(in); int ftxt[] = { 'F','T','X','T' }; if(head != makeID(ftxt)) { std::cerr << "Error: not a FTXT format IFF file.\n"; return false; } while(! in.eof()) { head = readID(in); size = readSize(in); if(size != 0) { if(onChunk(in, out, head, size) == false) break; } } char end[] = "\n}"; out << end; return false; } //------------------------------------------------------------- unsigned long TEDConverter::readSize(std::istream & in) { unsigned long size; int a[4]; if(in.eof()) return 0; a[0] = in.get(); if(in.eof()) return 0; a[1] = in.get(); if(in.eof()) return 0; a[2] = in.get(); if(in.eof()) return 0; a[3] = in.get(); #ifdef DEBUG std::cerr << "Sz: " << a[0] << " " << a[1] << " " << a[2] << " " << a[3] << std::endl; #endif size = makeID(a); return size; } //------------------------------------------------------------- unsigned long TEDConverter::readID(std::istream & in) { unsigned long id; int a[4]; a[0] = in.get(); a[1] = in.get(); a[2] = in.get(); a[3] = in.get(); #ifdef DEBUG std::cerr << "ID: " << a[0] << " " << a[1] << " " << a[2] << " " << a[3]; std::cerr << " = " << (char)a[0] << (char)a[1] << (char)a[2] << (char)a[3] << std::endl; #endif return makeID(a); } //------------------------------------------------------------- unsigned long TEDConverter::makeID(int * buff) { unsigned int *tbuff = (unsigned int *)buff; unsigned long id = 0; unsigned long t; for(int i = 0; i < 4; i ++) { t = (unsigned long)(tbuff[0]); tbuff ++; id = id << 8; id |= (unsigned long)t; } return id; } //------------------------------------------------------------- bool TEDConverter::onChunk(std::istream &in, std::ostream & out, unsigned long chunk, unsigned long size) { static int tcpp_parts[] = { 'T','C','P','P' }; static int tcph_parts[] = { 'T','C','P','H' }; static int chrs_parts[] = { 'C','H','R','S' }; if(chunk == makeID(tcpp_parts)) { onTCPP( in, out, size); } else if(chunk == makeID(tcph_parts)) { onTCPH( in, out, size); } else if(chunk == makeID(chrs_parts)) { onCHRS( in, out, size); } else { in.seekg( (int)in.tellg() + size ); } // must be even if(size & 1) in.get(); return true; } //------------------------------------------------------------- bool TEDConverter::onTCPP(std::istream &in, std::ostream & out,unsigned long sz) { in.seekg( (int)in.tellg() + sz ); return true; } //------------------------------------------------------------- bool TEDConverter::onTCPH(std::istream &in, std::ostream & out,unsigned long sz) { in.seekg( (int)in.tellg() + sz ); return true; } //------------------------------------------------------------- bool TEDConverter::onCHRS(std::istream &in, std::ostream & out,unsigned long sz) { int c; int last = 0; for(unsigned long i=0;i