Når vi tænker på Adobe Photoshop, tænker vi ofte på dets kraftfulde værktøjer, dets intuitive (eller nogle gange komplekse) brugerflade og de fantastiske billeder, det hjælper os med at skabe. Men hvad ligger der egentlig bag programmet? Hvilke instruktioner driver denne software, der revolutionerede digital billedbehandling? For at forstå dette må vi se på programmet 'indefra' – på dets kildekode.
Dette er udgangspunktet for Critical Code Studies (CCS), en tilgang der betragter computerkode som en kulturel tekst. CCS forsøger ikke kun at forstå koden ud fra dens funktionelle formål, men også dens 'ekstrafunktionelle' aspekter og kulturelle implikationer. Som Mark C. Marino, en fremtrædende fortaler for CCS, udtrykker det, handler det om at lære at forstå ikke kun, hvordan kode fungerer, men også hvordan den 'betyder' noget. Kildekode bliver dermed et vindue til den digitale kultur, den er en del af. I dette tilfælde lover Adobe Photoshops kildekode at give os et indblik i kulturen omkring digital billedbehandling og digital visuel kultur generelt.

Indtil for nylig har CCS-studier primært fokuseret på mindre programmer eller korte kodeafsnit. En af grundene til dette er, at kildekoden for de fleste kommercielle programmer er en tæt bevogtet hemmelighed. Adobe har dog gjort koden for en af de tidligste versioner af Photoshop tilgængelig via Computer History Museums hjemmeside i 2013. Selvom Photoshop har gennemgået utallige iterationer siden lanceringen i 1990, og den oprindelige kodebase for længst er forældet, giver version 1.0.1 for Apple Macintosh Computere fra 1990 os en unik mulighed for at se præcis, hvordan 'den digitale billedmanipulationsrevolution' blev implementeret helt fra starten.
Hvad er Kildekode?
Meget kort fortalt er kildekode den menneskeligt læsbare 'tekst' af et computerprogram. Den er skrevet i et programmeringssprog af menneskelige programmører og bliver derefter automatisk oversat til programmets kørbare form (binær maskinkode), før det kan afvikles på en computer. Af forskellige årsager kan kildekoden til Photoshop 1.0.1 ikke let oversættes til en kørende applikation i dag. Men vi har adgang til koden, og vi kan læse den og forsøge at forstå den.
Men hvordan kan en person, der er uddannet i mediehistorie og -teori – ikke en datalog eller softwareingeniør – håbe på at forstå og analysere den underliggende tekst i et computerprogram? CCS-fortalere anerkender, at 'programmeringskundskaber' er nøglen til Critical Code Studies. Jeg vil dog argumentere for, at humanister ikke behøver at blive dygtige programmører for at praktisere CCS. At kunne læse og forstå kode på et grundlæggende niveau er én ting; at kunne skrive ny, kompleks kode er noget helt andet. Ligesom vi ikke forventer, at filologer kan skrive nye episke digte på akkadisk, bør vi heller ikke forvente, at CCS-forskere udvikler den næste version af Photoshop.
Da programmeringssprogs 'ekspressive' potentiale er langt mindre end naturlige sprogs (primært på grund af syntaktiske begrænsninger), kan de nødvendige læsefærdigheder for CCS være lavere end dem, der kræves for dybdegående litterær analyse. Desuden har nogle argumenteret for, at kodelæsning alene sjældent er tilstrækkeligt til at forstå et programs faktiske indhold, da programmets 'funktionsdomæne' overstiger kodens kompleksitet. Hvis dette er sandt, kan det faktisk gavne CCS-udøvere, da det, vi søger i CCS, ofte ligger 'uden for' selve koden. Når humanister læser kildekoden til et billedbehandlingsprogram, er de interesserede i spørgsmål om digitale billeders status, ændringer i fotografisk praksis, visuelitetens skiftende natur osv. Disse er ikke kun 'tekniske', men i høj grad kulturelle spørgsmål. Kildekoden skal blot fungere som et 'indgangspunkt' eller et vindue til den digitale kultur.
Derfor tror jeg, at min mangel på formel træning i computerprogrammering ikke vil udgøre et alvorligt problem for forsøget på at læse kildekoden til Photoshop. Selvom jeg havde et halvt års kursus i Pascal i gymnasiet i 1990'erne, er min viden om programmering kun selvlært på begynderniveau. Min forståelse af kode som den i Photoshop 1.0.1 bygger på denne rudimentære viden og ressourcer fundet online. Forvent derfor ikke en dybdegående analyse af Photoshops interne detaljer, algoritmer eller datastrukturer. Jeg forventer heller ikke at finde 'skjulte perler' med det samme. Til at starte med håber jeg på intet mere end en generel idé om programmets design – et første overblik over koden, der kan give mig et foreløbigt kort til de følgende analysetrin.
Hvor skal man starte?
I modsætning til de mindre programmer og kortere kodeuddrag, som CCS hidtil har koncentreret sig om, præsenterer Adobe Photoshop 1.0.1 os for det særlige problem: hvor skal man begynde at læse koden? Selv den første udgave af programmet omfatter titusindvis af linjer kildekode. I princippet kunne vi dykke ned hvor som helst eller forsøge at finde den 'faktiske begyndelse'. Begge tilgange er dog problematiske.
Programmels størrelse og arkitektur modstår både den lineære, udtømmende læsning, vi ville give en roman, og – i starten i hvert fald – den tilfældige udvælgelse af enkelte dele. Som CCS-udøvere kan vi ikke håbe på at læse og forstå programmet i sin helhed fra start til slut. Og vi kan heller ikke håbe på at forstå dets bidrag til digital visuel kultur ved tilfældigt at vælge små bidder. Vi har brug for et overblik over 'programteksten', et layout af kildekoden, der lader os beslutte, hvor vi skal fokusere efter en indledende, overfladisk vurdering.
Desværre findes der ingen retningslinjer i CCS for, hvordan man griber 'store' programmer som Adobe Photoshop an. CCS har mig bekendt intet at sige om, hvilke strategier og værktøjer man skal bruge, når man arbejder med meget store kodebaser. Der findes endnu ikke et metodisk rammeværk for analyse og fortolkning af PC-forbrugerapplikationer på kildekodeniveau inden for CCS. Derfor må jeg simpelthen finde på det undervejs.
Filernes Struktur
Lad os først se, hvordan kildekoden faktisk ser ud, når man tilgår den via Computer History Museums hjemmeside. Efter at have accepteret licensaftalen kan man downloade en ZIP-fil kaldet photoshop-v.1.0.1-source-code.zip. Når arkivet pakkes ud, præsenteres man for et stort antal filer – i alt 179. Dette er forventeligt; selv beskedne programmers kildekode er rutinemæssigt opdelt i flere filer af hensyn til bekvemmelighed og modularitet.
Hvad handler disse 179 filer om? I stedet for at gennemgå indholdet af hver fil én efter én, lad os først forsøge at lave en form for meget grundlæggende 'distant reading' af Photoshops kildekode som en samling af filer. Allerede inden vi kigger ind i de enkelte filer og undersøger koden i detaljer, kan vi udlede nyttig information om Photoshops kildekode blot ved at se på filnavnene og deres størrelse.
De fleste filnavne antyder i det mindste, hvad koden indeni relaterer sig til. Flere filer ser ud til at svare direkte til specifikke billedredigeringsfunktioner i programmet, som beskæring, størrelsesændring eller rotation af billeder (f.eks. UCrop., UResize. og URotate.). Andre implementerer sandsynligvis de filformater, der understøttes af denne tidlige version af Photoshop, som EPS, GIF og TIFF (UEPSFormat., UGIFFormat. og UTIFFormat.). Endnu andre navne peger på teknikker og algoritmer, der bruges til behandling og lagring af billeddata (f.eks. ULZWCompress. eller UVMemory.). Der er fem filer, der bærer selve programmets navn (MPhotoshop.p, Photoshop.make, Photoshop.r, UPhotoshop.inc1.p, UPhotoshop.p). Kun en håndfuld filnavne er så generiske eller gådefulde (f.eks. Black.r, Tables. eller UGhost.), at vi ikke umiddelbart kan gætte, hvad koden handler om. En ting, der skiller sig ud, når man ser på filnavnene, er, at størstedelen, helt præcist 156 filer, starter med et stort 'U', som i UCrop., UGIFFormat. og UVMemory.. Vi vender tilbage til denne særegenhed senere.
Tilsyneladende er kildekoden til Adobe Photoshop struktureret i individuelle filer langs grænserne for specifikke funktioner, grænseflader og interne 'mekanismer' i programmet. Denne struktur indikerer en af de to vigtigste programmeringsparadigmater, som Photoshop følger (og som, ikke overraskende, kaldes struktureret programmering). Den kan også vise sig nyttig senere i vores kritiske kodestudie, da den giver os mulighed for markant at indsnævre mængden af kode, vi skal undersøge, når vi analyserer udvalgte dele af Photoshop.
Filendelser og Sprog
Dernæst vil vi se på filendelserne. Hver fil i kildekode-arkivet har en suffiks til sit navn, som f.eks. .p eller .r, der angiver filens type. Som nævnt på CHM-hjemmesiden blev Photoshop primært skrevet i programmeringssproget Pascal med nogle yderligere dele kodet i assembly-instruktioner til Mac'ens Motorola 68000 CPU. Derfor er det rimeligt at antage, at filendelsen .p står for Pascal-kilde filer, mens .a står for assembly-sprogs filer. En hurtig optælling viser 94 .p-filer over for 21 .a-filer, et forhold der understøtter denne antagelse. (Faktisk er filer, der ender på .inc, også Pascal-sprogsfiler, hvilket bringer forholdet mellem Pascal og assembly-filer op på 144:21).
Et kig ind i to tilsvarende filer (URotate.p og URotate.a) bekræfter vores hypotese om sammenhængen mellem filendelse og programmeringssprog.
Pascal: Et Højniveau Sprog
Dette er et eksempel på Pascal-kode (uddrag fra URotate.p):
FUNCTION DoRotateCommand (view: TImageView; angle: INTEGER): TCommand;VAR doc: TImageDocument; aRotateImageCommand: TRotateImageCommand; aRotateFloatCommand: TRotateFloatCommand;BEGIN IF angle = 1800 THEN DoRotateCommand := DoFlipCommand (view, TRUE, TRUE) ELSE BEGIN doc := TImageDocument (view.fDocument); IF EmptyRect (doc.fSelectionRect) THEN BEGIN NEW (aRotateImageCommand); FailNil (aRotateImageCommand); aRotateImageCommand.IRotateImageCommand (view, angle); DoRotateCommand := aRotateImageCommand END ELSE BEGIN NEW (aRotateFloatCommand); FailNil (aRotateFloatCommand); aRotateFloatCommand.IRotateFloatCommand (view, angle); DoRotateCommand := aRotateFloatCommand END ENDEND;
Bemærk elementerne fra et højniveau sprog: variabler og funktioner med beskrivende navne (som DoRotateCommand og angle) og betingede sætninger som IF ... THEN ... ELSE. Denne kode er relativt let at læse og forstå for et menneske, selv uden dyb teknisk viden.
Assembly: Et Lavnivea Sprog
På den anden side ser assembly-kode således ud (uddrag fra URotate.a):
SEG 'ADoRotate'DoReverseBytes PROC EXPORT; Calling sequence (Pascal conventions):; PROCEDURE DoReverseBytes (data: Ptr; ; count: INTEGER);; Parameter Offsets@data EQU 10@count EQU 8; Size of parameters@params EQU 6; Unload parametersLINK A6,#0MOVE.L @data(A6),A0MOVE.W @count(A6),D0; Compute address of one pixel past lastMOVE.L A0,A1ADDA.W D0,A1; Reverse the bytesASR.W #1,D0SUB.W #1,D0BMI.S @2@1 MOVE.B (A0),D1 MOVE.B -(A1),(A0)+ MOVE.B D1,(A1) DBF D0,@1; Clean up and exit@2 UNLK A6 MOVE.L (SP)+,A0 ADD.W #@params,SP JMP (A0)
Bemærk den gentagne brug af korte mnemotekniske koder for lavniveau 68K Motorola maskininstruktioner (som MOVE., ADD. og SUB.) og adressering af CPU-registre (såsom A0 og D0). Forskellen mellem højniveau Pascal og lavniveau assembly er markant. Assembly-koden indeholder flere kommentarer (linjer, der starter med semikolon), der forklarer, hvad der sker, mens den mere abstrakte, men beskrivende Pascal-kode tilsyneladende ikke behøver yderligere forklaringer.
Andre Filtyper
Lad os afslutte vores korte gennemgang af filendelserne. Udover .p, .a og .inc, finder vi også .make, .r, .t og .txt.
.txt: Bruges kun én gang for den selvforklarende filChangeHistory.txt, som indeholder menneskeligt læsbar information om ændringer..inc: Disse filer er korte og ser kun ud til at indeholde referencer til funktioner og procedurer defineret i Pascal-filerne. De kan sandsynligvis betragtes som tilføjelser til hoved-Pascal-filerne..make: Der er tre.make-filer, hvorafPhotoshop.makeer den vigtigste. Den refererer til de andre kilde filer og fortæller compileren, hvordan programmet skal bygges. Den indeholder ingen algoritmer af interesse for os, men viser, hvordan filerne hænger sammen..r: FraPhotoshop.makelærer vi, at filer, der ender på.r, er 'RezFiles'. Et kig ind i en af disse filer viser data kodet i heksadecimal form. For eksempel indeholderUAbout.rsandsynligvis bitmap-data for programmets 'Om Photoshop...' dialogboks..t: De to filer, der ender på.t(Huffman1.togHuffman2.t), indeholder tabeller af heltal og binære tal, der tydeligt repræsenterer en Huffman-kode til lossless datakompression.
For at opsummere:
| Filendelse | Sprog / Indhold | Formål |
|---|---|---|
.p, .inc |
Pascal | Hovedkode for programlogik og funktioner |
.a |
Assembly | Lavniveau kode for ydeevnekritiske opgaver |
.r |
RezFile (Data) | Indeholder ressourcer som billeder (bitmaps), UI-elementer, etc., ofte i heksadecimal form |
.t |
Data | Indeholder datastrukturer, f.eks. kompressionstabeller |
.make |
Makefile | Instruktioner til at kompilere og bygge programmet |
.txt |
Tekst | Menneskeligt læsbar information (f.eks. ændringshistorik) |
Kodens Størrelse
Som det sidste skridt i vores indledende overblik eller 'distant reading' af Photoshops kildekode, vil vi se på kodens størrelse.
For at få en generel fornemmelse af størrelsen kan vi først sammenligne filstørrelser. Af de ti største filer i kildekode-arkivet er seks Pascal-filer, to er 'Rez'-filer, og én er en assembly-fil. Den største fil er Photoshop.r (ca. 218 KB), så den vil vi helt sikkert kigge nærmere på senere. Den mindste af top-ti er assembly-filen USeparation.a (ca. 66 KB).
De ti mindste filer er alle .inc-filer og kun få linjer lange. Samlet set udgør Pascal-filerne (.p og .inc) ca. 2 MB, assembly-filerne (.a) ca. 388 KB, og 'data'-filerne (.r og .t) ca. 384 KB. Filstørrelsesforholdet mellem Pascal, Assembly og Data er altså ca. 72% til 14% til 14%, eller groft sagt 5:1:1.
Antal Kodelinjer (LOC)
Filstørrelser er en udmærket indikator for kodens størrelse, men den mest almindelige metrik er antallet af 'lines of code' (LOC), også kaldet 'source lines of code' (SLOC). Generelt svarer én kodelinje til én instruktion eller 'kommando' i et givet sprog. Ved at bruge værktøjer som wc eller det mere specialiserede program cloc kan vi tælle linjer. Den samlede sum af fysiske linjer i Pascal- og assembly-filerne er 116.587. Men kilde filer indeholder ofte linjer med kun kommentarer og tomme linjer til visuel organisering, som ikke tæller som egentlig kode.
Ved at bruge cloc, som kan skelne mellem kode, kommentarer og tomme linjer, får vi et mere præcist billede:
------------------------------------------------------------------------------- Language files blank comment code-------------------------------------------------------------------------------Pascal 144 32070 2767 63004Assembly 21 4867 5651 8228-------------------------------------------------------------------------------SUM: 165 36937 8418 71232-------------------------------------------------------------------------------
Som det ses, udgør tomme linjer og kommentarer en betydelig del af filerne. I assembly-filerne er mere end halvdelen af linjerne tomme eller kommentarer, mens omkring en tredjedel af linjerne i Pascal-filerne er tomme. cloc bekræfter også, at assembly-delen er mere kommenteret end Pascal-delen; kommentar-til-kode-forholdet er ca. 6:7 i assembly, men kun 1:23 i Pascal. Og vigtigst af alt, hvis vi kun tæller linjer med faktisk kode, er forholdet mellem Pascal og assembly ikke 5:1 (baseret på filstørrelse), men mere som 10:1! Hvis man ekskluderer .make, .r og .t filerne og kun medregner assembly og Pascal LOC, består Photoshops kildekode af 88% Pascal.
Endelig et par ord om den samlede størrelse af Photoshops kildekode. Tæller vi alle fysiske linjer i alle filer, inklusive tomme og kommentarer, får vi i alt 128.602 linjer. Sammenlignet med nuværende PC-applikationer virker dette lille: kildekoden til Mozillas Firefox-browser har 21 millioner linjer kode, over 160 gange mængden af Photoshops LOC! Softwarestørrelsen er dog eksploderet siden de tidlige 1990'ere, og i modsætning til nutidens team- eller endda crowd-baserede softwareudvikling, blev Photoshop primært skrevet af én enkelt softwareingeniør, Thomas Knoll. En bedre sammenligning kan være et program som MacPaint, den banebrydende grafikeditor skrevet til den originale Apple Macintosh i 1984 af Bill Atkinson, kun seks år før Photoshops udgivelse. Ifølge CHM-hjemmesiden, der hoster MacPaints kildekode, måler programmet blot 9.405 fysiske LOC. Vi kan konkludere, at Photoshop sandsynligvis var et stort program efter datidens standard. Under alle omstændigheder er over hundrede tusind linjer bestemt mere end nok for os at tackle i et kritisk kodestudie.
Konklusion og Forhåndsvisning
Intet af det, vi hidtil har gjort, udgør naturligvis en dybdegående analyse af Adobe Photoshops faktiske kildekode – mindst af alt et kritisk kodestudie af programmet. Men med vores indledende 'distant reading' af koden har vi taget det vigtige første skridt at få et overblik over kildearkivet, en generel idé om kodens struktur, de anvendte sprog, og hvordan programmet er fordelt på individuelle filer. Vi har identificeret den centrale .make-fil, der binder alt sammen til kompilering, samt .r og .t filerne, der indeholder kodede data af forskellig art. Fra filnavnene og lejlighedsvise kig ind i filerne har vi fået en idé om, hvor vi skal lede efter kodeafsnit vedrørende specifikke funktioner eller komponenter af programmet. Og vi har gjort det ved hjælp af intet andet end meget simple instrumenter som almindelige filhåndteringer og grundlæggende Unix-kommandolinjeværktøjer plus et dedikeret program til at tælle LOC og yderligere ressourcer, der let findes på internettet.
Næste gang vil vi dykke dybere ned i Pascal og Assembly sprogene, der blev brugt til Photoshop, se om vi kan udtrække mere information fra kilde filerne ved hjælp af standard Unix-kommandolinjeværktøjer og måske endda begynde at 'pille' ved udvalgte kodestykker. Så hvis du er interesseret, kom endelig tilbage til del II!
Ofte Stillede Spørgsmål
- Hvad er Critical Code Studies (CCS)?
- CCS er en akademisk tilgang, der analyserer computerkode som en kulturel tekst for at forstå dens betydning og kulturelle implikationer ud over dens funktionelle formål.
- Hvorfor studere kildekoden til en gammel version af Photoshop?
- Adobe har gjort koden til Photoshop 1.0.1 tilgængelig, hvilket giver et sjældent indblik i, hvordan digital billedbehandling blev implementeret i programmets tidlige dage. Det fungerer som et vindue til den digitale visuelle kultur på det tidspunkt.
- Skal man være programmør for at lave Critical Code Studies?
- Nej, ikke nødvendigvis en dygtig programmør. Et grundlæggende kendskab til programmeringssproget er nødvendigt for at kunne læse koden, men målet er at tolke koden kulturelt, ikke at kunne genskabe programmet.
- Hvilke programmeringssprog blev brugt i Photoshop 1.0.1?
- Programmet blev primært skrevet i Pascal med dele i Assembly sproget for Mac'ens Motorola 68000 CPU.
- Hvor stor var Photoshop 1.0.1's kildekode?
- Den samlede kildekode består af 179 filer med ca. 128.602 fysiske linjer eller ca. 71.232 linjer faktisk kode (LOC). Det blev betragtet som et stort program for sin tid.
- Hvad indeholder filerne med endelserne .r og .t?
- Disse filer indeholder data snarere end programkode. .r (RezFiles) indeholder ressourcer som billed-bitmaps til brugergrænsefladen, ofte i heksadecimal form. .t filer indeholder datastrukturer som f.eks. tabeller til Huffman-kompression.
Hvis du vil læse andre artikler, der ligner Indblik i Photoshops Kildekode, kan du besøge kategorien Software.
