[MUSIK SPELA] ZAMYLA CHAN: Det var Miss Scarlett med ljusstaken. DECKARE? Nåväl, vi ska ta reda på. I brädspelet Clue, kanske du ges en fysisk röda bilden. Och den bilden är väldigt röd och fläckig, och ditt jobb är att avslöja dolda budskap. Och brukar du försedd med en röd förstoringsglas, eller en röd skärm till avslöjar att dolda budskap. Nåväl, vi kommer att efterlikna det. I deckare, du får en bitmappsbild som ser mycket prickig och röd, och sedan köra DECKARE programmet att visa ett dolt budskap. Så låt oss bryta detta i steg. Först vill du att öppna filen - den ledtråd som du har fått. Och då också skapa en dom bitmap-fil. Då du vill uppdatera bitmapp header information för domen utfil. Mer om det senare. Och då du kommer att läsa in den ledtråd, scanline, pixel för pixel, ändra färgerna pixel som nödvändigt, och skrivning de i domen - pixel för pixel in i dom scanline. Hur ska vi börja gå om det här? Nå, som tur har vi copy.c i distributionskoden. Och detta kommer att visa sig ganska bra för oss. Copy.c öppnar en fil, läser av att infil sidhuvud, och uppdaterar sedan utfil nick. Och sedan läser varje pixel i scanline, pixel för pixel, och sedan skriver att pixel i utfil. Så ditt första steg kanske vara att köra följande kommando i terminalen - cp copy.c whodunit.c. Detta kommer att skapa en kopia av copy.c namnges whodunit.c. Så vår första steg för att öppna fil, det är väl en exakt replik av det i copy.c. Så jag lämnar er att titta på det. Vad vi har att göra med i denna PSET är fil-I / O, i princip ta filer, läsa, skriva, redigera dem. Hur öppnar du först en fil? Tja, du kommer att deklarera en fil pekare, och sedan ringa Funktionen fopen. Pass i vägen, eller namnet på det fil, och sedan det läge som du vill öppna filen i. Passning i ett r öppnas foo.bmp för läsning. Av följande skäl: fopen med passerar i en w kommer öppen bar.bmp, för att skriva filen och faktiskt redigera den. Så nu när vi har öppnat filen, vår Nästa steg är att uppdatera sidhuvudet info för utfil. Vad är en header information? Tja, först måste vi veta vad en bitmapp är. En bitmapp är bara en enkel arrangemang av byte. Och de deklareras i den här filen Här, bmp.h, med ett gäng Information om vad en bitmapp är faktiskt gjord av. Men vad vi verkligen bryr oss om är det bitmap-fil header, just här, och bitmappen info header, här borta. Huvudet består av ett par av variabler som kommer att vara mycket användbar. Det finns biSizeImage, som är den totala storleken på bilden i byte. Och detta inkluderar bildpunkter och utfyllnad. Padding är mycket viktigt, men vi kommer till det senare. BiWidth representerar bredden på den bilden i bildpunkter minus stoppning. BiHeight är då också höjden av bildpunkter. Och sedan BITMAPFILEHEADER och BITMAPINFOHEADER, som jag nämnde tidigare, är de som representeras som structs. Så kan du inte komma åt filen header själv, men du kommer att vilja komma till dessa variabler inuti. OK. Så hur ska vi uppdaterar rubrik information? Tja, först måste vi se om vi behöver ändra någon information från den infil, ledtråd, till utfil, domen. Finns det något att ändra i det här fallet? Tja, egentligen inte, eftersom vi ska att bara ändra färgerna. Vi kommer inte att ändra filen storlek, bildstorlek, bredden, eller höjden. Så du är okej för nu genom bara kopierar varje pixel. OK. Så nu ska vi titta på hur vi faktiskt kan läsa varje pixel från filen. En annan fil I / O-funktion kommer in i bilden - fread. Det tar en pekare till struct som kommer att innehålla de bytes som du läser. Så du läser in i det. Och då du passerar i en storlek, som är storleken på varje element som du vill läsa. Här funktionen sizeof kommer väl till hands. Då du passerar i antal, vilket representerar antalet element i storlek för att läsa. Och sedan slutligen, inptr, vilket är filen pekare som du är går att läsa från. Så alla dessa element är inne inptr och de ska data. Låt oss titta på ett litet exempel. Om jag vill läsa till data två hundar, Tja, jag kan göra det på två sätt. Jag kan antingen läsas på två föremål av storlek hund från min inptr, eller jag kan läsa i en protes storleken på två hundar. Så du ser att beroende på hur att du ordnar storlek och antal, du kan läsas i samma antal byte. Så nu ska vi ändra pixel färg som vi behöver. Om man tittar på bmp.h igen, då ser du att längst ner RGBTRIPLEs är en annan struct, där De består av tre bitgrupper. Ett, rgbtBlue, rgbtGreen och rgbtRed. Så var och en av dem representerar den mängd blå, mängden grönt, och mängd rött inuti denna pixel, där varje belopp representeras av en hexadecimalt nummer. Så ff0000 blir en blå färg, eftersom det går från blå, till grönt till rött. Och sedan alla f s kommer att vara vit. Låt oss ta en titt på smiley.bmp, vilket du har i din distribution kod. Om du öppnar det på bara en bild betraktaren, då du kommer bara se en röd smiley. Men att ta en djupare dykning i, vi ska se att strukturen det är bara bildpunkter. Vi har vita pixlar, och sedan röda pixlar. Den vita, ffffff, och sedan alla röda pixlar jag färgade in för dig här, och du ser att de är 0000ff. Noll blå, noll grön och fullt rött. Och eftersom smiley är åtta pixlar bred, Vi har ingen utfyllnad. Okej. Så om jag skulle tilldela olika värden till en RGBTRIPLE och jag ville göra det grönt, vad jag skulle göra är Jag skulle förklara en RGBTRIPLE, som heter trippel, och sedan komma åt alla byte inom den struct jag skulle använda punktoperatorn. Så triple.rgbtBlue, jag kan tilldela den till 0. Grön Jag kan koppla den till fullo - alla nummer, verkligen, mellan 0 och ff. Och sedan rött, jag också kommer att säga 0. Så då det ger mig en grön pixel. Nästa, tänk om jag vill kontrollera värdet av något? Jag skulle kunna ha något som kontrollerar om triple s rgbtBlue värde är ff och sedan skriva ut, "Jag känner mig blå ", som följd. Nu, som inte nödvändigtvis att pixeln är blå, eller hur? Eftersom pixel gröna och röda värden kan också ha icke-0-värden. Allt som detta innebär, och allt det där detta kontrollerar för är för en fullständig blå färg. Men alla bildpunkter kan också ha delvis färgvärden, som den här Nästa exempel här. Det är lite svårare att se vad denna bild är nu. Detta ser lite mer ut som den clue.bmp att du kommer att ges. Nu, fysiskt, kan du lösa detta, eftersom det finns en hel del rött, genom håller upp en röd skärm på bilden så att de andra färger kan visas. Så hur ska vi efterlikna det med c? Tja, kan vi ta bort alla röda från bilden helt. Och så för att göra att vi skulle sätta alla pixel röda värdet till 0. Och så att bilden skulle se lite lite så här, där vi inte har någon röd helst. Vi kan se det dolda budskapet en lite tydligare nu. Det är en annan smiley. Eller kanske kunde vi använda en annan metod. Kanske kunde vi identifiera alla de röda pixlar - det vill säga, samtliga bildelement med 0 blå, 0 grön, och 0 röd - och ändra dem till vitt. Och vår bild kan se ut ungefär så här. Lite lättare att se. Det finns många andra sätt att avslöja det hemliga budskapet också, behandlar färgmanipulering. Kanske du kan använda någon av metoderna som jag nämnde ovan. Och dessutom, kanske du vill för att förbättra vissa färger och ta med dem ut. Så nu när vi har ändrat pixeln färg, nästa vi behöver bara skriva dem in till scanline, pixel för pixel. Och ännu en gång, men du vill se tillbaka att copy.c, om du inte har kopierat det redan, och titta på fwrite funktion, som tar data, en pekare till den struct som innehåller byte att du läser från, storleken på objekten, antalet objekt, och därefter outptr - destinationen för dessa filer. När du skriver i bildpunkter, kommer du också behöva skriva i stoppningen. Vad är utfyllnad? Tja, varje rgbt pixel är tre byte lång. Men, det scanline för en bitmappsbild måste vara en multipel av fyra byte. Och om antalet pixlar är inte multipel av fyra, då måste vi lägga denna stoppning. Padding är bara representeras av 0: or. Så, hur ska vi skriva eller läsa det här? Jo, det visar sig att du inte kan faktiskt fread stoppning, men du kan beräkna den. I det här fallet, den ledtråd och domen ha samma bredd, så stoppning är densamma. Och stoppningen, som du ser i copy.c, beräknas med nedanstående formel - bi.biWidth gånger sizeof (RGBTRIPLE) kommer att ge oss hur många byte den bmp har i varje rad. Därifrån modulos och subtraktioner med 4 kan beräkna hur många byte måste tillsättas så att multipeln av byte på varje rad är fyra. Nu när vi har formeln för hur mycket stoppning vi behöver, nu Vi kan skriva det. Nu, nämnde jag tidigare, stoppning är bara 0: or. Så i det fallet, vi bara sätta en röding, i detta fall en 0, in i vår outptr - vår utfil. Så som kan bara vara fputc 0, kommatecken outptr. Så, medan vi har läst i vår fil, har fil-I / O hållit koll på vår ställning på dessa filer med något heter filen lägesindikator. Se det som en markör. I grund och botten, avancerar det varje gång att vi fread, men vi har kontroll över det också. För att flytta filen lägesindikator, Du kan använda funktionen fseek. Om inptr representerar filen pekare som du söker i, den beloppet är antalet byte som du vill flytta markören, och sedan från hänför sig till referenspunkten från där markören är. Om du passerar i SEEK_CUR, att representerar den aktuella position i filen. Eller så kan du använda några andra parametrar. Så kanske vi vill använda fseek att hoppa över stoppningen av i filen. Och återigen, om du har fastnat, det finns ett exempel på det i copy.c. Så nu har vi öppnat filen, ledtråd, och domen. Vi har uppdaterat rubriken information för vår dom, eftersom varje bitmapp behöver en rubrik. Vi har sedan läsa in i ledtråd s scanline, pixel för pixel, ändra varje färg som behövs, och skriver de in i dom, pixel för pixel. När du öppnar dom, kan du se vem den skyldige, eller vad hemligheten budskap är. Mitt namn är Zamyla, och detta var DECKARE.