[Música tocando] ZAMYLA CHAN: Foi señorita Scarlett co castiçal. Whodunit? Ben, imos descubrir. No Clue xogo de mesa, pode ser dada unha imaxe vermella física. E esa imaxe é moi vermello e irregular, eo seu traballo é revelar a mensaxe oculta. E, xeralmente, está equipado cun vermello lupa, ou unha pantalla vermella para revelan que a mensaxe oculta. Ben, nós estamos indo a imitar iso. Na novela policial, está dado unha imaxe bitmap que se parece moi irregular e vermello, e, a continuación, realizar o programa whodunit para revelar unha mensaxe oculta. Entón, imos romper iso en etapas. En primeiro lugar, quere abrir o arquivo - a pista que lle foi dado. E despois tamén crear un arquivo veredicto bitmap. Entón quere actualizar o mapa de bits cabeceira información para o outfile veredicto. Máis sobre iso máis tarde. E entón vai ler na pista, scanline, pixel por pixel, cambiando as cores do pixel como necesario, e escrita aqueles en que o veredicto - pixel por pixel na scanline veredicto. Como é que imos comezar a ir a este respecto? Ben, por sorte, temos copy.c no código de distribución. E iso vai probar moi útil para nós. Copy.c abre un ficheiro, le nese cabeceira do infile, e actualiza o cabeceira do ficheiro de saída. E, a continuación, le-se cada pixel na scanline, pixel por pixel, e, a continuación, escribe que de píxeles para o arquivo de saída. Entón, o primeiro paso pode a de realizar o seguinte orde na terminal - cp copy.c whodunit.c. Isto creará unha copia de copy.c chamado whodunit.c. Así, o noso primeiro paso para abrir o arquivo, así, hai unha exacta réplica do que en copy.c. Entón, eu vou deixar ollar para iso. O que estamos lidando neste PSET é ficheiro E /, basicamente tomando arquivos, lectura, escritura, editalos. Como abrir un arquivo? Ben, está indo a declarar un ficheiro punteiro, e despois chamar o función fopen. Pase no camiño, ou o nome da ficheiro e, a continuación, o xeito que quere para abrir este ficheiro dentro Pasando unha r abrirá foo.bmp á lectura. Considerando fopen con pasando un w vai bar.bmp aberto, para gardar o ficheiro e realmente editalo. Polo tanto, agora que abriu o ficheiro, o noso seguinte paso é actualizar a información da cabeceira para o arquivo de saída. ¿Que é unha información de cabeceira? Ben, primeiro necesitamos saber o que é un mapa de bits é. Un mapa de bits é só un simple arranxo de bytes. E eles están declarados neste arquivo aquí, bmp.h, con unha morea de información do que un mapa de bits é realmente feita de fóra. Pero o que realmente importa é o cabeceira do ficheiro de mapa de bits, así aquí, e a información bitmap cabeceira, aquí. A cabeceira está formado por un par de variables que pode ser moi útil. Hai biSizeImage, que é o tamaño da imaxe en bytes. E iso inclúe píxeles e estofado. Padding é moi importante, pero nós imos chegar a iso máis tarde. BiWidth representa a anchura da imaxe en píxeles menos o estofado. BiHeight é entón tamén a altura da imaxe en píxeles. E, a continuación, o BITMAPFILEHEADER ea BITMAPINFOHEADER, como mencionei anterior, aqueles representados como estruturas. Entón, vostede non pode acceder a cabeceira do ficheiro si mesmo, pero vai querer comezar a estas variables dentro. Aceptar. Entón, como imos actualizar a información da cabeceira? Ben, primeiro temos que ver se nós Debe cambiar calquera información do o infile, a pista, co outfile, o veredicto. Calquera cousa está cambiando neste caso? Ben, non realmente, porque nós imos para ser só cambiando as cores. Non imos estar cambiando o arquivo o tamaño, o tamaño da imaxe, a anchura, ou a altura. Entón, está ben por agora por só copiando cada pixel. Aceptar. Entón agora imos ollar como nós, en realidade, pode ler cada pixel do arquivo. Outro arquivo función I / O vai entrar en xogo - fread. Ten en un punteiro para a struct que conterá os bytes estás lendo. Entón está lendo para iso. E entón pasa nun tamaño, que é o tamaño de cada elemento que lle quere ler. Aquí, a función sizeof virá a cadra. Entón pasa en número, que representa o número de elementos de tamaño de ler. E, a continuación, por fin, inptr, que é o punteiro do ficheiro que está indo a ler. Entón, todos estes elementos están dentro inptr e están indo a datos. Vexamos un pequeno exemplo. Se quero ler en datos de dous cans, ben, eu podo facelo de dous xeitos. I pode ler en dous obxectos de tamaño can do meu inptr, ou podo ler nun obxecto do tamaño de dous cans. Entón ve que, dependendo da forma que organice tamaño e número, pode ler o mesmo número de bytes. Entón, agora, imos cambiar o píxeles de cor como necesitamos. Se ollar para bmp.h novo, entón podes ver que na parte inferior RGBTRIPLEs son outra estrutura, onde eles constan de tres bytes. Un, rgbtBlue, rgbtGreen, e rgbtRed. Así, cada un deles representa a cantidade de azul, a cantidade de verde, eo cantidade de vermello dentro deste píxel, onde cada valor é representado por un número hexadecimal. Entón FF0000 será unha cor azul, porque vai de azul, a verde, a vermella. E entón, f será de branco. Imos dar un ollo a smiley.bmp, que ten no seu código de distribución. Se abrilo en só unha imaxe espectador, entón basta ver un Smiley vermello. Pero tomar un mergullo máis profundo en, imos ver que a estrutura de que é só píxeles. Temos píxeles brancos, e logo, vermello píxeles. O branco, ffffff, e entón todo o píxeles vermellos Eu cores en para ti aquí, e ve que están 0000ff. Cero azul, verde cero, e cheo vermello. E xa que Smiley é de oito píxeles de ancho, non temos ningún recheo. Todo ben. Entón, se eu fose para asignar valores distintos a un RGBTRIPLE e eu quería facelo verde, entón o que me gustaría facer é Quere declarar un RGBTRIPLE, nomeado triple, logo para acceder cada byte en que a estrutura I usaría o operador punto. Entón triple.rgbtBlue, podo asignar que a 0. Verde podo atribuílo lo a foto - calquera número, en realidade, entre 0 e ss. E, a continuación, vermello, eu tamén vou dicir a 0. Entón iso me dá un pixel verde. A continuación, o que se eu queira comprobar o valor de algo? Podería ter algo que comprobar O valor rgbtBlue do triplo é ff e, a continuación, imprimir, "Estou me sentido azul ", como un resultado. Agora, iso non significa necesariamente que o pixel é azul, non? Como os valores verdes e vermellas do píxeles Tamén pode ter valores non-0. Todo o que iso significa, e todo o que este está comprobando é a unha cor azul completa. Pero todos os píxeles tamén podería parcial valores de cor, como este seguinte exemplo aquí. É un pouco máis difícil de ver o que esta imaxe é agora. Isto parece un pouco máis parecido ao clue.bmp que vai ser dada. Agora, fisicamente, pode resolver iso, porque hai unha morea de vermello, por sostendo unha pantalla vermella para a imaxe de xeito que as outras cores poden aparecer. Entón, como podemos imitar esta con c? Así, podemos eliminar todo vermello a partir da imaxe totalmente. E así facer que iríamos establecer cada valor vermello pixel a 0. E así a imaxe quedaría un pouco pouco como este, onde non temos vermello calquera. Podemos ver a mensaxe dunha oculta pouco máis claramente agora. É máis un rostro sorrinte. Ou quizais poderiamos usar outro método. Quizais, poderiamos identificar todos os píxeles vermellos - é dicir, todos os píxeles con 0 azul, verde 0 e 0 vermello - e cambiar aqueles para branco. E a nosa imaxe pode parecer algo así. Un pouco máis fácil de ver. Hai moitas outras formas de descubrir a mensaxe secreta, así como, xestione o manexo de memoria. Quizais pode usar un dos métodos que eu mencionen anteriormente. E ademais, pode querer para mellorar algunhas cores e levar os para fóra. Polo tanto, agora que nós cambiamos o píxel cor, xunto só necesitamos gravala-los en que a liña de varrido, pixel por pixel. E unha vez máis, vai querer ollar cara atrás para copy.c, se non copiou xa, e mirar para o fwrite función, a cal leva datos, un punteiro para a estrutura que contén o bytes que estás lendo a partir, o tamaño da os elementos, o número de elementos, e, a continuación, o outptr - o destino deses arquivos. Despois de escribir nos píxeles, vai Tamén ten que escribir no estofado. Qué é o recheo? Ben, cada pixel RGBT é de tres bytes. Pero a liña de varrido dunha imaxe de mapa de bits para ten que ser un múltiplo de catro bytes. O número de píxeles non é un múltiplo de catro, entón necesitamos engadir este recheo. O recheo é só representado por 0s. Entón, como é que imos escribir ou ler isto? Ben, acontece que non pode estofado realmente fread, pero pode calcula-lo. Neste caso, a pista eo veredicto teñen o mesmo ancho, de xeito que o acolchado é a mesma. E o recheo, como podes ver en copy.c, calcúlase coa seguinte fórmula - bi.biWidth veces sizeof (RGBTRIPLE) vai deixa-nos cantos bytes a bmp ten en cada liña. De alí, os módulos e restas con 4 pode calcular canto debe ser engadido a fin de que moitos bytes o múltiplo de bytes en Cada liña é catro. Agora que temos a fórmula como estofado que necesitamos agora podemos escribilo. Agora, eu mencionen antes, recheo é só 0s. Entón, nese caso, estamos só poñendo char, neste caso, un 0, a nosa outptr - noso outfile. Entón isto pode ser só fputc 0, coma outptr. Así, mentres nós temos a lectura na nosa arquivo, ficheiro E / mantivo o control da nosa posición neses ficheiros con algo chamado o indicador de posición de arquivo. Pense nisso como un cursor. Basicamente, ela avanza cada vez que fread, pero temos control sobre iso, tamén. Para mover o indicador de posición de arquivo, pode usar a función fseek. Cando o inptr representa o ficheiro punteiro que está a buscar, en, a importe é o número de bytes que quere mover o cursor e logo, desde refírese ao punto de referencia desde onde está o cursor. Se pasar en SEEK_CUR, que representa o actual posición no ficheiro. Ou pode empregar algúns outros parámetros. Entón, a xente pode querer usar fseek para saltar sobre o recheo do ficheiro en. E, de novo, se está preso, non hai un exemplo de que, en copy.c. Entón, agora nós abrimos o arquivo, a pista, eo veredicto. Nós actualizamos a información da cabeceira para noso veredicto, que cada bitmap precisa dun cabeceira. Entón Nós lemos na pista de scanline, pixel a pixel, cambiando todas as cores que corresponda, e escribindo aqueles no veredicto, pixel por pixel. Unha vez que abrir o veredicto, pode ver quen o culpable, ou cal é o segredo mensaxe. O meu nome é Zamyla e este era whodunit.