[Powered by Google Translate] [Walkthrough - Problem Set 4] [Zamyla Chan - Harvard University] [Dette er CS50. - CS50.TV] Ok. Hej, alle sammen, og velkommen til Walkthrough 4. I dag er vores Pset er Forensics. Forensics er et virkelig sjovt Pset der involverer beskæftiger sig med bitmapfiler at opdage, der har begået en forbrydelse. Så vi kommer til at ændre størrelsen nogle bitmapfiler, så er vi også kommer til at beskæftige sig med en virkelig sjov del kaldet Recover, hvor vi dybest set udleveret et hukommelseskort hvor nogen har uheld slettet alle deres filer, og vi bliver bedt om at gendanne disse filer. Men først, før vi kommer ind i Pset, jeg virkelig bare ønsker at lykønske alle. Vi er ved i midtpunktet af dette kursus. Quiz 0 er bag os, og vi er ved pset4, så det væsentlige, vi er halvvejs. Vi er kommet en lang vej, hvis man ser tilbage på dine psets, pset0 og pset1, så lykønske dig selv om det, og vi vil komme ind i nogle rigtig sjove ting. Så vores værktøjskasse til denne Pset, igen, i stedet for at køre sudo yum-y update, vi er i stand til at bare køre update50 hvis du er i version 17,3 og derover af apparatet. Så sørg for at køre update50 - det er en hel del lettere, et par mindre bogstaver - at sikre, at du er på den nyeste version af apparatet. Især er det vigtigt at update50 når vi begynder at bruge CS50 Check. Så sørg for at du gør det. For alle sektionerne for denne Pset, vi kommer til at beskæftige sig med fil input og output, fil I / O. Vi vil være at gå over en masse programmer, der beskæftiger sig med arrays peger på filer og sådan noget, så vi ønsker at sikre, at vi er virkelig kender og behageligt beskæftiger sig med, hvordan man input og output til filer. I fordelingen kode for denne Pset er en fil, der hedder copy.c, og det er hvad vi vil finde vil være virkelig nyttige for os fordi vi kommer til at ende op faktisk kopiering af copy.c fil og blot ændre den lidt for at kunne nå de første 2 dele af problemet sæt. Og så derefter som jeg nævnte før, har vi at gøre med bitmaps samt JPEG. Så virkelig at forstå strukturen af, hvordan disse filer er organiseret, hvordan vi virkelig kan oversætte 0'er og 1-taller i struct og ting, som vi rent faktisk kan forstå og fortolke og redigere, der vil være virkelig vigtigt, så gå ind i JPEG og bitmap-filer og forstå strukturen af ​​dem. Pset4 som sædvanlig starter med et afsnit med spørgsmål. Dem vil beskæftige sig med file I / O og få dig vant til det. Så del 1 er krimi, hvor du får en bitmap-fil der ser lidt ligesom røde prikker over det hele. Og så dybest set, hvad vi vil gøre er at tage denne fil og bare redigere det lidt ind i en version, som vi kan læse. Væsentlige, når vi er færdig, vil vi have den samme fil, medmindre vi vil være i stand til at se det skjulte budskab skjult af alle de røde prikker. Så Resize er et program, der givet en fil og derefter givet navnet på den fil, det output og derefter givet et nummer så godt, rent faktisk vil ændre størrelsen at bitmap ved at heltalsværdi. Så endelig har vi Recover Pset. Vi får et hukommelseskort og derefter nødt til at inddrive alle de billeder der utilsigtet er blevet slettet, men, som vi vil lære, faktisk ikke slettet og fjernet fra filen; vi bare lidt tabt, hvor de var i filen, men vi vil komme det. Great. Så gå ind i fil I / O specifikt disse er en hel liste over funktioner, som du skal bruge. Du har allerede set en lille smule det grundlæggende i fopen, fread og fwrite, men vi vil se nærmere på nogle fil I / O-funktioner såsom fputc, hvor du bare skrive et tegn ad gangen, til fseek, hvor du slags flytte filen position indikator frem og tilbage, og derefter nogle andre. Men vi vil gå ind i det lidt senere under Pset. Så det første, at bare komme ind i fil I / O, inden vi går ind i Pset, at åbne en fil, for eksempel, er hvad du skal gøre rent faktisk sætte en pointer til den pågældende fil. Så vi har en FILE * pointer. I dette tilfælde, jeg kalder det en i pointer, fordi det kommer til at blive min infile. Og så jeg har tænkt mig at bruge funktionen fopen og derefter navnet på filen og derefter den tilstand, som jeg har tænkt mig at beskæftige sig med sagen. Så der er "r" i dette tilfælde for læsning, "w" til skrivning, og derefter "a" for at tilføje. For eksempel, du når at gøre med en infile og alt hvad du ønsker at gøre, er at læse de bits og bytes gemt der, så er du sikkert lyst til at bruge "r" som din tilstand. Når du ønsker at faktisk skrive, slags lave en ny fil, så hvad vi vil gøre, er at vi vil komme til at åbne den nye fil og bruge "w" mode for at skrive. Så når du rent faktisk læser i de filer, strukturen er som følger. Først skal du inkludere markøren til struct, der indeholder de bytes, du læser. Så det vil være enden placeringen af ​​de bytes, du læser. Du derefter gå til at angive størrelsen, gerne dybest set hvor mange bytes Deres program er at læse i til filen, størrelsen dybest set et element er, og så du kommer til at angive, hvor mange elementer, du vil læse. Og så til sidst, er du nødt til at vide, hvor du læser fra, så der kommer til at være din i pointer. Jeg farvekodet disse, fordi fread er også meget lig fwrite, medmindre du vil være sikker på, at du bruger den rigtige rækkefølge, sørg for, at du rent faktisk er at skrive til eller læse fra den rigtige fil. Så derefter som før, hvis vi har størrelsen af ​​elementet samt antallet af elementer, så vi kan spille rundt her en lille smule. Sige, at jeg har en hund struct og så derefter jeg vil læse to hunde ad gangen. Hvad jeg kunne gøre, er at sige størrelsen på et element vil være på størrelse med en hund og jeg har tænkt mig at rent faktisk at læse to af dem. Alternativt hvad jeg kunne gøre sige jeg bare at læse et element og at et element vil være på størrelse med to hunde. Så det er analog, hvordan du kan slags leg rundt med størrelse og antal afhængigt af, hvad der er mere intuitivt for dig. Ok. Så nu får vi at skrive filer. Når du ønsker at skrive en fil, det første argument er faktisk hvor du læser fra. Så det er dybest set de data, du vil skrive i filen, som er ud pointer i slutningen. Så når du har at gøre med Pset, så sørg for at du ikke bliver forvirrede. Måske har definitionerne side om side. Man kan trække definitionerne i manualen ved at skrive mennesker og derefter fwrite for eksempel i terminalen, eller du kan henvise tilbage til dette dias og sørg for, at du bruger den rigtige. Så igen, for fwrite, når du har en fil, som du vil skrive i, der kommer til at være den sidste argument og det kommer til at være en pegepind til denne fil. Så det er, hvordan vi behandler skrive måske flere bytes ad gangen, men siger du bare lyst til at skrive på blot en enkelt karakter. Som vi vil se senere i dette eksempel, i de bitmaps vi bliver nødt til at bruge den. Det er, når vi kan bruge fputc, hovedsagelig bare at sætte et tegn ad gangen, chr, i filen pointer, og det er vores ud pointer der. Så når vi søge eller skrive i en fil, filen er at holde styr på, hvor vi er. Så det er en slags markør, filen position indikator. Og så når vi skriver eller læser igen ind i en fil, filen faktisk husker, hvor det er, og så det fortsætter fra hvor markøren er. Dette kan være en fordel, når du vil, sige, læse i et bestemt beløb til at gøre noget og derefter læse i følgende beløb, men nogle gange er vi måske ønsker at gå tilbage eller faktisk starter fra en bestemt referenceværdi. Altsaa fseek funktionen, hvad det gør, er giver os mulighed for at flytte markøren i en bestemt fil et vist antal bytes. Og så, hvad vi skal gøre, er angive, hvor referenceværdien er. Så enten det bevæger sig frem eller tilbage fra hvor markøren i øjeblikket er, eller vi kan angive, at det bare skal bevæge sig ind fra begyndelsen af ​​filen eller fra slutningen af ​​filen. Og så du kan passere i negative eller positive værdier til beløb, og det vil slags flytte markøren enten fremad eller bagud. Før vi kommer ind i de andre psets, spørgsmål om fil I / O? Okay. Da vi kommer ind flere eksempler, er du velkommen til at stoppe mig for spørgsmål. Så i krimi, er du udleveret en bitmap-fil ligner denne rød ligger på rutschebanen, og det ser sådan her ud - en flok røde prikker - og du ikke rigtig ved hvad der er skrevet. Hvis du squint, kan du være i stand til at se en svag blålig farve inde i midten. Væsentlige, det er, hvor teksten er gemt. Der var et mord, der er sket, og vi er nødt til at finde ud af, hvem der gjorde det. For at gøre det, vi er nødt til at slags konvertere dette billede til et læsbart format. Hvis du fyre nogensinde er stødt på, nogle gange ville der være lidt kits hvor du ville have en lup med en rød film. Anyone? Yeah. Så du ville være handed noget som dette, ville du have en lup med den røde film over det, ville du sætte den over billedet, og du ville være i stand til at se den besked skjult deri. Vi har ikke et forstørrelsesglas med rød film, så i stedet vil vi slags skabe vores egen i dette Pset. Og så brugeren kommer til input krimi, så fingerpeg. Bmp, så det er den infile, det er den røde prik besked, og så de siger verdict.bmp bliver vores outfile. Så det kommer til at skabe et nyt bitmap billede ligner den fjerneste anelse undtagen i et læsbart format, hvor vi kan se den skjulte budskab. Da vi kommer til at beskæftige sig med redigering og manipulere bitmaps af en slags, vi kommer til at slags dyk i ind strukturen af ​​disse bitmap-filer. Vi gik over disse lidt i foredrag, men lad os se på dem nogle flere. Bitmaps er i det væsentlige blot et arrangement af bytes hvor vi har angivet hvilke bytes betyder hvad. Så her er lidt ligesom et kort over bitmapbilledet siger, at det starter med nogle header-filer, starter med nogle oplysninger derinde. Du ser, at ved ca byte nummer 14 størrelsen er angivet af den bitmapbillede, og det fortsætter på. Men hvad vi virkelig er interesseret i her begynder omkring byte nummer 54. Vi har disse RGB tripler. Hvad der kommer til at gøre, er at indeholde de faktiske pixels, farveværdierne. Alt over det i headeren er nogle oplysninger svarende til størrelsen af ​​billedet, bredden af ​​billedet, og højden. Når vi går ind i polstring senere, vil vi se, hvorfor størrelsen på billedet kan være anderledes end bredden eller højden. Så derefter at repræsentere disse - disse bitmapbilleder er sekvenser af byte - hvad vi kunne gøre, er at sige okay, jeg skal huske, at på indeks 14, det er hvor størrelsen er for eksempel, men i stedet hvad vi vil gøre for at gøre det lettere er indkapsle det i en struct. Og så har vi to struct lavet for os, en BITMAPFILEHEADER og en BITMAPINFOHEADER, og så når vi læser i denne fil, som standard, det vil være at gå i orden, og så for det er også vil udfylde i variabler såsom biWidth og biSize. Og så til sidst, er hver pixel repræsenteres af tre bytes. Den første er mængden af ​​blå i pixel, det andet er mængden af ​​grønt, og endelig den mængde af rødt, hvor 0 er væsentlige ingen blå eller ingen grønne eller ingen rød og derefter ff er den maksimale værdi. Disse er hexadecimale værdier. Så hvis vi har ff0000, så det svarer til den maksimale mængde blå og så er ingen grøn og ingen rød, ja så der ville give os en blå pixel. Så hvis vi har ff all over hele linjen, så det betyder, at vi har en hvid pixel. Det er en slags modsat typisk når vi siger RGB. Det er faktisk går BGR. Så hvis vi rent faktisk se på et eksempel på et bitmapbillede - lad mig trække en op her. Det er lidt lille. Jeg zoomer ind, og vi kan se det er pixeleret. Det ligner farvede blokke. Du har hvide blokke og derefter røde blokke. Hvis du spiller i Microsoft Paint, for eksempel, kunne du lave sådan noget ved egentlig bare male bestemte kvadrater i en bestemt rækkefølge. Så hvad dette omsættes til i bitmap er som følger. Her har vi første hvide pixels, at alle 6 er f er, og så har vi røde pixels, angivet med 0000FF. Og så sekvens af bytes, som vi har viser, hvordan bitmapbilledet kommer til at se ud. Så hvad jeg har gjort her, er lige skrevet ud af alle disse bytes, og derefter farvet i rød så du kan slags se, hvis du skele lidt, hvordan den slags indikerer et smilende ansigt. Den måde, at bitmap billeder arbejde er jeg forestiller det dybest set som et gitter. Og så som standard, har hver række i gitteret til at være et multiplum af 4 byte. Hvis vi ser på et bitmapbillede, du udfylder hver værdi. For eksempel kan du have en rød her, en grøn her, en blå her, men du skal sørge for, at billedet er udfyldt med et multiplum af fire bytes. Så hvis jeg vil have mit billede til at være tre blokke bred, så ville jeg nødt til at sætte en tom værdi i den sidste til at gøre det til et multiplum af fire. Så da jeg ville tilføje i noget, som vi kalder polstring. Jeg skal bare til at indikere, at der med en x. Nu siger vi ønsker et billede, som er 7 pixels lang, for eksempel. Vi har 1, 2, 3, 4, 5, 6, 7, og alt dette udfyldes med farve. Den måde, at bitmapbilleder arbejde er, at vi har brug for en 8.. Lige nu har vi 1, 2, 3, 4, 5, 6, 7. Vi har brug for 8 pladser til bitmapbilledet at læse korrekt. Så hvad vi skal gøre er at tilføje i blot en smule polstring at sikre, at alle bredder er ensartet og at alle bredder er et multiplum af fire. Og så jeg tidligere angivet, polstring som en x eller en bølgede linje, men i selve bitmapbilleder polstringen er angivet med en hexadecimal 0. Så det ville være et enkelt tegn, 0. Hvad kan komme i handy er den XXD kommando. Hvad det gør, er faktisk viser dig, som svarer til, hvad jeg gjorde før med smiley når jeg faktisk printet ud, hvad hver farve ville være for pixel og derefter farvekodet det, når du kører XXD med følgende kommandoer, så vil det rent faktisk udskrive hvad farverne er for de pixels. Hvad du skal gøre er herovre jeg oplyse, ligesom-s 54 siger, at jeg har tænkt mig at starte på den 54. byte fordi før at huske, hvis vi ser tilbage til kortet over de bitmaps, det er alt header information og sådan noget. Men hvad vi virkelig bekymrer sig om, er de faktiske pixels, der angiver farven. Så ved at tilføje i denne flag,-s 54, så vi er i stand til at se farveværdierne. Og du behøver ikke bekymre dig om de komplicerede flag og den slags. I det problem indstillede spec, har du anvisninger på, hvordan man bruger XXD at vise pixels. Så hvis du ser her, den slags ligner en grøn boks, denne lille ting. Jeg har farvekodet den 00ff00 som dybest set sige nej blå, en masse grønt, og ingen røde. Så det svarer til grøn. Som du kan se her, ser vi en grøn firkant. Denne grønne rektangel er kun 3 pixels bred, så derefter hvad vi skal gøre at sikre, at billedet er et multiplum af 4 bred, er at tilføje i ekstra polstring. Og så så det er sådan du ser disse 0'er her. Det vil faktisk være resultatet af din Resize Pset, væsentligt under den lille bitmap og derefter udvider det med 4. Og så det, vi ser, er, at der faktisk dette billede er 12 pixels bred, men 12 er et multiplum af 4, og så vi faktisk ikke se nogen 0'er i slutningen, fordi vi ikke behøver at tilføje nogen fordi den fuldstændigt er polstret. Det har ikke noget mere plads. Okay. Eventuelle spørgsmål om polstring? Okay. Cool. Som jeg nævnte før, de bitmaps er blot en sekvens af bytes. Og så hvad vi har, er i stedet for at skulle holde styr på præcis hvilke antal byte svarer til et bestemt element, vi faktisk har skabt en struct til at repræsentere det. Så hvad vi har, er en RGBTRIPLE struct. Når du har en forekomst af et RGB triple, fordi det er en type definere struct, så du kan få adgang til rgbtBlue variabel, tilsvarende er de grønne og røde variabler, som vil indikere, hvor meget blå, grøn og rød, henholdsvis du har. Så hvis vi har den blå variabel sat til 0, den grønne sæt til ff, som er den maksimale værdi, du kan få, og derefter det røde variablen sat til 0, så hvad farve ville denne særlige RGB triple repræsentere? >> [Studerende] Green. Grøn. Præcis. Det kommer til at være nyttigt at vide, at når du har en forekomst af et RGB triple, du kan faktisk få adgang til mængden af ​​farve - blå, grøn og rød - hver for sig. Nu, hvor vi har talt om strukturen af ​​det, så lad os tage et kig på BMP-fil. Disse er struct lavet til dig. Her har vi en BITMAPFILEHEADER struct. Af interesse er størrelsen. Senere har vi info header, som har et par flere ting, som er interessant for os, nemlig størrelse, bredden og højden. Som vi vil gå ind senere, når du læser i til filen, den automatisk læser i, fordi vi har indstillet for at være den samme. Så biSize vil indeholde de rette bytes, der svarer til den faktiske størrelse af billedet. Og så her til sidst, da vi har talt om, har vi RGBTRIPLE typedef struct. Vi har en rgbtBlue, Grøn og Rød forbundet med det. Great. Okay. Nu, hvor vi forstår bitmaps en lille smule, forstå, at vi har en fil header og en info header forbundet med det, og så efter det, vi har interessante ting af farverne, og disse farver er repræsenteret ved RGBTRIPLE struct, og dem, til gengæld har tre værdier forbundet til den blå, den grønne og den røde. Så nu kan vi slags tænke på Recover en smule. Undskyld. Tænk krimi. Når vi har vores clue fil, så hvad vi ønsker at gøre, er at læse i den pixel for pixel og derefter en eller anden måde ændre de pixels, så vi kan udlæse det til et læsbart format. Og så at udskrive det, vi kommer til at skrive pixel for pixel i verdict.bmp fil. Det er lidt meget at gøre. Vi indser, at. Så hvad vi har gjort, er at vi har faktisk givet dig copy.c. Hvad copy.c gør, er bare gør en nøjagtig kopi af en given bitmap-fil og derefter sender det ud. Så dette allerede åbner filen for dig, lyder i pixel for pixel, og derefter skriver det i ind i en output-fil. Lad os tage et kig på det. Dette er at sikre korrekt anvendelse, få filnavnene her. Hvad dette betyder er det sætter inddatafilen at være, hvad vi har gået i i infile her, som er vores anden kommando-line argument. Kontrol for at sikre, at vi kan åbne filen. Kontrol for at sikre, at vi kan lave en ny outfile her. Så hvad dette betyder her, det bare dybest set begynder at læse i den bitmap-fil fra begyndelsen. Begyndelsen, som vi ved, indeholder BITMAPFILEHEADER, og så disse sekvenser af bits vil direkte udfylde BITMAPFILEHEADER. Så hvad vi har her siger, at BITMAPFILEHEADER bf - Det er vores nye variabel af typen BITMAPFILEHEADER - vi kommer til at sætte inde bf hvad vi læser fra i pointer, som er vores infile. Hvor meget skal vi læse? Vi læser i hvor mange bytes vi nødt til at indeholde hele BITMAPFILEHEADER. Ligeledes, det er hvad vi gør for info header. Så vi fortsætter langs vores fil i infile, og vi læser disse bits og bytes, og vi tilslutte dem direkte i i disse tilfælde af de variabler, som vi gør. Her er vi bare at gøre sikker på, at bitmap er en bitmap. Nu har vi en outfile, right? Så som det står når vi skaber det, det er det væsentlige tom. Så vi er nødt til at dybest set oprette en ny bitmap fra bunden. Hvad vi gør, er vi nødt til at sørge for, at vi kopierer i filens header og info header ligesom infile har. Hvad vi gør, er vi skriver - og husk, at bf er den variable af typen BITMAPFILEHEADER, så hvad vi gør, er vi bare bruge det indhold at skrive ind i outfile. Her husker vi talte om polstring, hvordan er det vigtigt at sørge for, at mængden af ​​pixels, som vi har, er et multiplum af 4. Dette er en smuk nyttig formel til at beregne, hvor meget polstring du har givet bredden af ​​din fil. Jeg vil have jer til at huske, at i copy.c har vi en formel for beregning polstring. Okay? Så alle huske. Great. Så hvad copy.c gør næste er det gentager over alle de scanlines. Det går gennem rækkerne først og derefter lagrer hver tredobbelt at den læser og skriver den i outfile. Så her er vi læser kun én RGB triple ad gangen og derefter sætte den samme tredobbelt i outfile. Den vanskelige del er, at polstringen ikke er et RGB-triple, og så vi kan ikke bare læse, at polstring mængden af ​​RGB tripler. Hvad vi skal gøre, er faktisk bare flytte vores fil position indikator, flytte vores markøren, at slags springe over alle padding, så vi er på den næste række. Og så, hvad dette gør, er at kopiere viser dig, hvordan du måske ønsker at tilføje polstring. Så vi har beregnet, hvor meget polstring vi har brug for, så det betyder, at vi har brug for polstring antal 0'er. Hvad dette gør, er en for-løkke, der sætter polstring antallet af 0s ind i vores outfile. Og så til sidst, du lukker begge filer. Du lukker infile samt outfile. Så det er sådan copy.c værker, og det kommer til at være temmelig nyttig. I stedet for bare faktisk direkte kopiere og indsætte det eller bare at kigge på det og skrive i, hvad du ønsker, du måske bare ønsker at udføre denne kommando i terminalen, cp copy.c whodunit.c, som vil oprette en ny fil, whodunit.c, , der indeholder præcis samme indhold som kopi gør. Så hvad vi kan gøre, er at bruge det som en ramme, som man kan opbygge og redigere for vores whodunit fil. Disse er vores gøremål at gøre for krimi, men hvad copy.c gør er faktisk tager sig af de fleste af dem for os. Så alt vi skal gøre næste er at ændre pixels efter behov til rent faktisk at gøre filen læsbar. Husk, at for en givet pixel tredobbelt, således for en given variabel af typen RGBTRIPLE, du kan få adgang til de blå, grønne og røde værdier. Det kommer til at komme i praktisk, fordi hvis du har adgang til dem, det betyder, at du også kan tjekke dem, og det betyder, at du også kan ændre dem. Så når vi gik tilbage til vores røde forstørrelsesglas eksempel, dybest set, blev der fungerer som en slags filter for os. Så hvad vi ønsker at gøre, er at vi ønsker at filtrere alle de tripler, der kommer i. Der er flere forskellige måder at gøre dette. Dybest set, kan du få uanset hvilken type filter, du ønsker. Måske du ønsker at ændre alle røde pixels eller måske du ønsker at ændre en anden farve pixel til en anden farve. Det er op til dig. Husk at du kan tjekke, hvad farve pixel er og så kan du også ændre det som du går igennem. Okay. Så det er krimi. Når du kører krimi, vil du vide, hvem synderen af ​​forbrydelsen var. Nu vil vi gå for at ændre størrelse. Vi vil stadig beskæftiger sig med bitmaps. Hvad vi vil gøre, er at vi vil have et input bitmap og så vi kommer til at passere i et nummer og derefter få en outfile bitmap hvor det er dybest set vores infile skaleret med n.. Sig min fil var blot én pixel stort. Så hvis min n var 3, skalering med 3, så vil jeg gentage, at pixel n antal gange, så 3 gange, og derefter også skalere den ned 3 gange så godt. Så du ser, jeg skalere den lodret såvel som vandret. Og så her er et eksempel. Hvis du har n = 2, kan du se, at den første blå pixel der gentages to gange vandret samt to gange lodret. Og så det fortsætter på, og så har du en direkte skalering af dit oprindelige billede med to. Så hvis vi skulle detalje pseudokoden for dette, vi ønsker at åbne filen. Og så at vide, at hvis vi går tilbage her, vi se, at bredden for outfile vil være anderledes end bredden for infile. Hvad betyder det? Det betyder, at vores header information kommer til at ændre sig. Og så, hvad vi skal gøre, er at opdatere header info, vel vidende, at når vi læser i de filer, hvis du opererer på copy.c rammer, vi allerede har en variabel, der angiver, hvad størrelsen er og sådan noget. Så når du har det, hvad du måske ønsker at gøre, er at ændre disse særlige variabler. Husk, hvis du har en struct, hvordan du får adgang til variable inden det. Du bruger dot operatør, right? Så derefter bruge det, du ved, at du bliver nødt til at ændre overskriften info. Så her er bare en liste over de konkrete elementer, der vil være ved at ændre i din fil. Filstørrelsen vil ændre sig og billedet, såvel som bredden og højden. Så derefter gå tilbage til kortet over de bitmaps, se på, om det er den fil header eller info header, der indeholder disse oplysninger og derefter ændre efter behov. Igen siger cp copy.c resize.c. Det betyder, at resize.c nu indeholder alt, hvad der er indeholdt inde kopi fordi kopi giver os en metode til at læse i hver scanlinie pixel for pixel. Undtagen nu, i stedet for bare at ændre de værdier, som vi gjorde i krimi hvad vi ønsker at gøre, er at vi ønsker at skrive i flere pixels så længe vores n er større end 1. Så hvad vi ønsker at gøre, er at vi ønsker at strække det vandret ved n, og strække det lodret ved n. Hvordan kan vi gøre det? Sig din n er 2 og du har dette givet infile. Markøren kommer til at starte på den første, og hvad du ønsker at gøre, hvis n er 2, du ønsker at udskrive i 2 af dem. Så du udskrive i 2 af dem. Så din cursor vil flytte til den næste pixel, som er den røde, og det kommer til at udskrive 2 i disse røde, tilføjende det på, hvad det er gjort før. Så markøren vil flytte sig til næste pixel og trække i 2 af dem. Hvis man ser tilbage til den copy.c ramme, hvad dette betyder lige her er det skaber en ny instans af en RGB-triple, en ny variabel kaldet triple. Og her når den læser ind i det, der læses fra infile 1 RGBTRIPLE og gemmer det inde i det tredobbelte variabel. Så du rent faktisk har en variabel, der repræsenterer den pågældende pixel. Så når du skriver, hvad du måske ønsker at gøre, er indramme fwrite erklæring i en for-løkke der skriver det ind i din outfile så mange gange som nødvendigt. Det er simpelt nok. Bare dybest set gentage skriveprocessen n antal gange for at skalere den vandret. Men så skal vi huske, at vores polstring kommer til at ændre. Tidligere sige, vi havde noget af længde 3. Så ville vi bare tilføje i hvor meget polstring? Blot én mere for at gøre det til en multipel på 4. Men siger, at vi skalere dette bestemt billede ved n = 2. Så hvor mange blå pixels ville vi have i slutningen? Vi ville have 6. 1, 2, 3, 4, 5, 6. Ok. 6 er ikke et multiplum af fire. Hvad er det nærmeste multiplum af 4? Det kommer til at være 8. Så vi faktisk kommer til at have 2 tegn i polstring der. Er der nogen huske, hvis vi har en formel til at beregne polstring og hvor det kunne være? [Uhørlig student svar] >> Yeah, copy.c. Right. Der er en formel i copy.c at beregne, hvor meget polstring du har givet en bestemt bredde af bitmapbillede. Så der kommer til at være nyttigt, når du har brug for at tilføje en vis mængde af polstring til rent faktisk at regne ud hvor meget polstring skal du tilføje. Men en note, er dog, at du vil være sikker på, at du bruger den rigtige størrelse. Bare vær forsigtig, fordi du dybest set kommer til at beskæftige sig med to bitmapbilleder. Du vil være sikker på, at du bruger den rigtige. Når du beregne polstring for outfile, du ønsker at bruge bredden af ​​outfile og ikke over bredden af ​​den foregående. Great. Den slags tager sig af at strække en hel bitmapbillede vandret. Men hvad vi ønsker at gøre, er faktisk strække det lodret så godt. Dette vil være en lille smule tricky, fordi når vi er færdige med at kopiere en række og skrive den pågældende række, er vores markør vil være i slutningen. Så hvis vi læser igen, så er det bare at læse i til den næste linje. Så hvad vi ønsker at gøre, er at slags finde en måde at kopiere disse rækker igen eller bare lidt at tage den pågældende række og derefter omskrivning det igen. Som jeg slags hentydet til, er der flere forskellige måder at gøre dette. Hvad du kan gøre, er da du går igennem og læsning gennem det særlige scanlinie og ændre det efter behov, og derefter slags lager alle disse pixels i et array. Så senere på du ved, at du bliver nødt til at udskrive denne opstilling igen, og så kan du bare bruge den opstilling til at gøre det. En anden måde at gøre det er du kunne kopiere ned én række, forstå, at du er nødt til at kopiere det igen, så faktisk flytte markøren, og det kommer til at bruge den metode fseek. Du kan flytte markøren helt tilbage og derefter gentage kopien processen igen. Så hvis vores skalering nummer er n, så hvor mange gange ville vi nødt til at gå tilbage og omskrive en linje? >> [Studerende] n - 1. >> Ja, perfekt. n - 1. Vi har gjort det en gang allerede, så så vil vi gerne gentage gå tilbage proces n - 1 antal gange. Okay. Så der har du din resize funktion. Nu kan vi komme til en rigtig sjov del, min favorit Pset, der er Recover. I stedet for bitmaps, denne gang vi har at gøre med JPEG. Vi er faktisk ikke givet en fil, blot af JPEG, vi er givet dybest set en rå hukommelseskort format. Og så denne indeholder en smule af info og skrald værdier i begyndelsen, og så det begynder, og det har en masse JPEG-filer. Men vi udleveret et kort, hvor vi har slettet billederne; væsentlige, har vi glemt, hvor billederne er placeret i kortet. Så vores opgave i Recover er at gå gennem dette kort format og finde de billeder igen. Heldigvis er strukturen af ​​JPEG-filer og kortets fil er lidt hjælpsom. Det absolut kunne have været en smule mere tricky hvis ikke det var i dette særlige format. Hver JPEG-fil faktisk starter med to mulige sekvenser, nævnt ovenfor. Dybest set, når du har en ny JPEG-fil, det starter med enten sekvensen ffd8 ffe0 eller den anden, ffd8 ffe1. En anden nyttig ting at vide er, at JPEG gemmes tilstødende. Så hver gang en JPEG fil ender, den anden starter. Så der er ikke nogen form for i-mellem værdier der. Når du rammer starten på en JPEG, hvis du allerede har læst en JPEG, du ved, at du har ramt enden af ​​den foregående og begyndelsen af ​​det næste. Til slags visualisere dette, gjorde jeg en skematisk. En anden ting om JPEG er, at vi kan læse dem i sekvenser af 512 byte ad gangen, ligeledes med begyndelsen af ​​kortet. Vi behøver ikke at være kontrol hver enkelt byte, fordi det ville sutte. Så i stedet, hvad vi kan gøre, er faktisk lige læst i 512 byte ad gangen og derefter, i stedet for at checke ind mellem dem i disse bitte små skiver, Vi kan bare se begyndelsen af ​​512 byte. Væsentlige, i dette billede, er hvad du ser i begyndelsen af ​​kortet, du har værdier, der ikke rigtig relevant for de faktiske JPEG selv. Men hvad jeg har, er en stjerne at angive et af de to startende sekvenser for en JPEG. Så når du ser en stjerne, du ved, at du har en JPEG-fil. Og derefter hver JPEG-fil vil være nogle flere på 512 bytes men ikke nødvendigvis de samme multiple. Den måde, du ved, at du har ramt en anden JPEG er, hvis du rammer en anden stjerne, anden start sekvens af bytes. Så hvad har du her er du har den røde JPEG-fil fortsætter, indtil du rammer en stjerne, som er angivet med en ny farve. Du fortsætter og så du rammer en anden stjerne, du rammer en anden JPEG, du fortsætte hele vejen indtil slutningen. Du er på det sidste billede her, den lyserøde. Du gå til enden, indtil du rammer slutningen af ​​filen karakter. Dette vil være virkelig nyttige. Et par vigtige grillbarer her: Kortet Filen starter ikke med en JPEG, men når en JPEG starter, er alle de JPEG lagrede side om side med hinanden. Nogle pseudokoden for Recover. Først vil vi åbne vores kartotek, og det kommer til at bruge vores fil I / O-funktioner. Vi kommer til at gentage følgende proces, indtil vi har nået slutningen af ​​filen. Vi kommer til at læse 512 bytes ad gangen. Og det, jeg sagde her er vi vil gemme det i en buffer, så dybest set holde på de 512 byte, indtil vi ved præcis, hvad de skal gøre med dem. Så hvad vi ønsker at gøre, er at vi ønsker at tjekke, om vi har ramt en stjerne eller ej. Hvis vi har ramt en stjerne, hvis vi har ramt en af ​​de startende sekvenser, så ved vi, at vi har ramt en ny JPEG-fil. Hvad vil vi gerne vil gøre, er at vi vil ønsker at oprette en ny fil i vores pset4 bibliotek at fortsætte med at foretage den pågældende fil. Men også, hvis vi allerede har lavet en JPEG før, så ønsker vi at afslutte denne fil og skubbe det til pset4 mappe, hvor vi vil få denne fil er gemt, fordi hvis vi ikke specificere, at vi er endt som JPEG-fil, så vil vi stort set har et ubestemt beløb. De JPEG vil aldrig ende. Så vi ønsker at sikre, at når vi læser ind på en JPEG-fil og skrive det, vi specifikt vil lukke, at for at åbne den næste. Vi ønsker at kontrollere flere ting. Vi ønsker at undersøge, om vi er i starten af ​​en ny JPEG med vores buffer og også hvis vi allerede har fundet en JPEG før fordi der vil ændre dit proces lidt. Så efter du er gået igennem hele vejen og du rammer slutningen af ​​filen, så hvad du ønsker at gøre, er du ønsker at lukke alle de filer, der er åbne. Det vil sandsynligvis være den sidste JPEG-fil, du har, samt det kort fil, du har med at gøre. Den sidste forhindring, som vi er nødt til at tackle, er, hvordan man faktisk gøre en JPEG-fil og hvordan man rent faktisk skubbe det til mappen. Det Pset kræver, at alle JPEG, at du finder være i følgende format, hvor du har nummeret. jpg. Antallet, selv om det er 0, kalder vi det 000.jpg. Når du finder en JPEG i dit program, du vil ønsker at navngive det i den rækkefølge, det er fundet. Hvad betyder dette? Vi er nødt til at slags holde styr på hvor mange vi har fundet og hvilken antallet af hvert JPEG bør være. Her vil vi drage fordel af den sprintf funktion. Svarende til printf, som bare lidt udskriver en værdi ud i terminalen, sprintf udskriver filen ud i mappen. Og så, hvad dette ville gøre, hvis jeg havde sprintf, titel og derefter strengen der, det ville udskrive 2.jpg. Antages det, at jeg har lukket mine filer korrekt, der ville indeholde den fil, jeg havde skrevet ud. Men én ting er, at den kode, jeg har her ikke helt opfylder hvad Pset kræver. Det Pset kræver, at den anden JPEG-fil skal navngives 002 i stedet for bare 2. Så når du udskriver navnet, så måske du måske ønsker at ændre pladsholderen lidt. Er der nogen huske, hvordan vi gør det muligt ekstra mellemrum, når vi udskriver noget? Yeah. >> [Studerende] Du sætter en 3 mellem procenttegn og 2. >> Ja, perfekt. Du vil sætte en 3 i dette tilfælde, fordi vi ønsker plads til 3. % 3d ville sandsynligvis give dig 002.jpg stedet for 2. Det første argument i sprintf funktion er faktisk en char array, som vi tidligere kendte som strenge. Dem vilje, slags mere som en midlertidig opbevaring, bare gemme den resulterende streng. Du vil ikke rigtig beskæftige sig med dette, men du er nødt til at inkludere den. Vel vidende, at hver fil navn har det antal, som fylder tre tegn, og derefter. jpg, hvor langt skal dette array være? Smid et nummer. Hvor mange tegn i titlen, i navnet? Så der er 3 hashtags, periode, jpg. >> [Studerende] 7. >> 7. Ikke helt. Vi kommer til at have 8, fordi vi ønsker at give mulighed for null terminator så godt. Endelig bare trække ud den proces, du skal gøre for Recover, du har nogle begyndelsen information. Du fortsætter indtil du finder starten på en JPEG-fil, og det kan være en af ​​de to udgangsmaterialer sekvenser. Du holder på at læse. Hver skråstreg her repræsenterer 512 bytes. Man holde på læsning, holde på læsning, indtil du møder en anden startsekvens. Når du har det, du ender den aktuelle JPEG - i dette tilfælde er det den røde, så du ønsker at ende det. Du ønsker at sprintf navnet på det i din pset4 mappe, så du ønsker at åbne en ny JPEG og derefter fortsætte med at læse indtil du støder den næste. Hold på læsning, holde på læsning, og så endelig til sidst, er du nødt til at nå slutningen af ​​filen, og så vil du ønsker at lukke den sidste JPEG som du arbejdede med, sprintf at i din pset4 mappe, og derefter se på alle de billeder, som du har fået. Disse billeder er faktisk billeder af CS50 medarbejdere, og så er det her den bonus sjove del af Pset kommer i er, at du konkurrerer i dine afsnit for at finde de TF'er på billederne og tage billeder med dem for at bevise, at du har gjort det Pset og så du kan se, hvilke medarbejdere er i billederne. Så du tager billeder med personalet. Nogle gange vil du nødt til at jage dem ned. Sandsynligvis nogle af dem vil forsøge at løbe væk fra dig. Du tager billeder med dem. Dette er igangværende. Det er ikke på grund af, når Pset skyldes. Fristen vil blive annonceret i spec. Så sammen med din afdeling, alt efter hvilken sektion tager de fleste billeder med flest ansatte vil vinde en temmelig awesome præmie. Det er lidt incitament til at få din pset4 færdig så hurtigt som muligt fordi så kan du komme ned til erhvervslivet jage alle de forskellige CS50 ansatte. Det er ikke obligatorisk, men så når du får billederne, så du er færdig med pset4. Og jeg er færdig med Walkthrough 4, så tak alle for at komme. Held og lykke med Forensics. [Bifald] [CS50.TV]