Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!eternal-september.org!feeder.eternal-september.org!mx02.eternal-september.org!.POSTED!not-for-mail From: Mark P M Lim Newsgroups: comp.sys.apple2.programmer Subject: UnpackBytes in Swift Date: Thu, 26 Feb 2015 14:05:26 +0000 (UTC) Organization: Mac GUI Lines: 111 Message-ID: Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Injection-Date: Thu, 26 Feb 2015 14:05:26 +0000 (UTC) Injection-Info: mx02.eternal-september.org; posting-host="ac9e0e4d7dd3957fb97803ee6801bab8"; logging-data="14314"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+lr0dXMFnAK2hHWEvNJgFK" User-Agent: Mac GUI Usenet Cancel-Lock: sha1:h7CLAVPeZQmYWU73TqMNZHAvGJ0= Xref: csiph.com comp.sys.apple2.programmer:1526 Hi, As part of an ongoing process to improve my coding skills, I decided to learn Apple's new programming language Swift. Naturally, the best approach in programming is to learn by doing a project. Since the people who are interested in Apple II graphics programming are in this newsgroup, I thought it might be appropriate to post the following code snippet (written in Swift, of course) here for comments on possible bugs: // Ref: http://kpreid.livejournal.com/4319.html & // of course, Andy Fadden's CiderPress source // The parameter packedData is the array of packed bytes func unpackBytes(packedData:[UInt8]) -> [UInt8] { enum PackedFormat : UInt8 { case AllDifferent = 0, RepeatNextByte, RepeatNext4Bytes, Repeat4ofNextByte } var unpackedData = [UInt8]() var srcLen = packedData.count var index = 0 // index into array of packed bytes while (srcLen > 0) { let flag = packedData[index++] let type = (flag & 0xc0) >> 6 var count = (flag & 0x3f) + 1 var rldBuf = [UInt8]() // Run Len Decoder buffer --srcLen if let whichFormat = PackedFormat(rawValue:type) { switch(whichFormat) { case .AllDifferent: for var i = 0; i < Int(count); ++i { rldBuf.append(packedData[index++]) --srcLen } case .RepeatNextByte: let repeatedVal = packedData[index++] --srcLen for var i = 0; i < Int(count); ++i { rldBuf.append(repeatedVal) } case .RepeatNext4Bytes: srcLen -= 4 var fourBytes = [UInt8](count:4, repeatedValue:0) fourBytes[0] = packedData[index++] fourBytes[1] = packedData[index++] fourBytes[2] = packedData[index++] fourBytes[3] = packedData[index++] for var i = 0; i < Int(count); ++i { rldBuf += fourBytes } case .Repeat4ofNextByte: let repeatedVal = packedData[index++] --srcLen var fourBytes = [UInt8](count:4, repeatedValue:0) fourBytes[0] = repeatedVal fourBytes[1] = repeatedVal fourBytes[2] = repeatedVal fourBytes[3] = repeatedVal for var i = 0; i < Int(count); ++i { rldBuf += fourBytes } } } unpackedData += rldBuf } return unpackedData } Sorry, if the formatting does not come out good. The function had been tested by passing packed scanlines from files with file/aux types 0xc0/0x0002 and entire files with file/aux types 0xc0/0x0001 As an exercise, I whip up a simple program written entirely in Swift that will load and display the following Apple IIgs 320x200 graphic files of the following format. 0xc0/0x0001, packed IIgs super-hires 0xc1/0x0000, unpacked IIgs super-hires 0xc0/0x0002, Apple Preferred format There is partial support for APF files. Only MAIN block is decoded; the rest of the blocks are ignored Currently program execution is slow; before a 320x200 graphic is displayed it must be decoded. Here's a screen capture of the window of the program. http://www.macgui.com/gallery/showphoto.php?pic_id=3493 A word of thanks to the person(s) who made available the graphics shown. Regards. Mark -- Mark Lim PM