JavaRush /Blog Java /Random-ES /Harvard CS50: Asignaciones de la semana 4 (Conferencias 9...
Masha
Nivel 41

Harvard CS50: Asignaciones de la semana 4 (Conferencias 9 y 10)

Publicado en el grupo Random-ES
Harvard CS50: Tareas de la cuarta semana (Conferencias 9 y 10) - 1

Preparándose para el trabajo

Como siempre, primero abra una ventana de terminal y ejecute el comando. update50 para asegurarse de que su solicitud ya esté actualizada. Antes de comenzar, siga esto cd ~ / workspace wget http://cdn.cs50.net/2015/fall/psets/4/pset4/pset4.zip para descargar un archivo ZIP de esta tarea. Ahora, si ejecuta ls , verá que tiene un archivo llamado pset4.zip en su directorio ~/workspace . Extráelo usando el comando: Si unzip pset4.zip vuelves a ejecutar el comando ls , verás que ha aparecido otro directorio. Ahora puede eliminar el archivo zip como se muestra a continuación: rm -f pset4.zip Abramos el directorio pset4 cd pset4 , ejecutemos ls y asegurémonos de que el directorio contenga bmp / jpg / questions.txt

novela policíaca o "¿Quién hizo esto?"

Si alguna vez ha visto el escritorio predeterminado de Windows XP (https://en.wikipedia.org/wiki/Bliss_(image)) (colinas y cielo azul), entonces ha visto BMP. En las páginas web, lo más probable es que hayas visto GIF. ¿Has mirado fotografías digitales? Entonces, tuvimos el placer de ver JPEG. Si alguna vez tomaste una captura de pantalla en una Mac, lo más probable es que hayas visto un PNG. Lea en Internet sobre los formatos BMP, GIF, JPEG, PNG y responda estas preguntas:
  1. ¿Cuantos colores soporta cada formato?

  2. ¿Qué formato admite animación?

  3. ¿Cuál es la diferencia entre compresión con y sin pérdidas?

  4. ¿Cuál de estos formatos utiliza compresión con pérdida?

Se recomienda a quienes hablen inglés que consulten el artículo del MIT . Si lo estudia (o encuentra otros recursos en Internet sobre el almacenamiento de archivos en discos y sistemas de archivos), podrá responder las siguientes preguntas:
  1. ¿Qué sucede desde un punto de vista técnico cuando se elimina un archivo en un sistema de archivos FAT?

  2. ¿Qué se puede hacer para garantizar (con una alta probabilidad) que los archivos eliminados no se puedan recuperar?

Y ahora, a nuestra historia, que fluye suavemente hacia la primera tarea de la cuarta semana. ¡Bienvenidos a la Mansión Tudor! El propietario de la finca, el señor John Boddy, nos abandonó repentinamente, siendo víctima de un oscuro juego. Para saber qué pasó, debes definir la novela policíaca . Desafortunadamente para usted (aunque aún más para el Sr. Boddy), la única evidencia que tiene es el archivo BMP de 24 bits.bmp . Es su contenido el que ves a continuación. El señor Boddy logró crearlo y guardarlo en su computadora en sus últimos momentos. El archivo contiene una imagen de novela policíaca escondida entre el ruido rojo . Ahora necesitas trabajar en la solución como un verdadero especialista técnico. Harvard CS50: Tareas de la cuarta semana (Conferencias 9 y 10) - 2Pero primero, algo de información. Probablemente sea más fácil pensar en una imagen como una cuadrícula de píxeles (es decir, puntos), cada uno de los cuales puede tener un color específico. Para establecer el color de un punto en una imagen en blanco y negro, necesitamos 1 bit. 0 puede representar negro y 1 puede representar blanco como se muestra en la siguiente imagen. Harvard CS50: Tareas de la cuarta semana (Conferencias 9 y 10) - 3Así, las imágenes representadas de esta forma son simplemente un mapa de bits (bitmap o mapa de bits, como se dice en inglés o en jerga). En blanco y negro todo es lo más sencillo posible, pero para obtener imágenes en color sólo necesitamos más bits por píxel. Un formato de archivo (como GIF) que admite "colores de 8 bits" utiliza 8 bits por píxel. Un formato de archivo (por ejemplo, BMP, JPG, PNG) que admite "color de 24 bits" utiliza 24 bits por píxel (BMP en realidad admite colores de 1, 4, 8, 16, 24 y 32 bits). . En el BMP de 24 bits que utiliza el Sr. Boddy, se necesitan 8 bits para indicar la cantidad de rojo, la misma cantidad para el verde y nuevamente 8 bits para indicar la cantidad de azul en cada píxel. Si alguna vez has oído hablar de los colores RGB , este es el lugar (R=rojo, G=verde, B=azul). Si los valores R, G y B de algún píxel en BMP son, digamos, 0xff, 0x00 y 0x00 en hexadecimal, entonces el píxel será rojo puro, ya que 0xff (también conocido como 255 en decimal) significa "mucho rojo". " en ese momento como 0x00 y 0x00 significan "sin verde" y "azul también ceros", respectivamente. Dado lo roja que nos parece la imagen BMP del Sr. Boddy, es intuitivo que el "compartimento" rojo tiene un valor claramente mayor que los "compartimentos" rojo y azul. Sin embargo, no todos los píxeles son rojos; algunos son claramente de un color diferente. Por cierto, en HTML y CSS (el lenguaje de marcado y las hojas de estilo que lo ayudan y que se utilizan para crear páginas web), los modelos de color están organizados de la misma manera. Si está interesado, consulte el enlace: https://ru.wikipedia.org/wiki/Colors_HTMLpara más detalles. Ahora abordemos el problema de forma más técnica. Recuerde que un archivo es simplemente una secuencia de bits dispuestos en algún orden. Un archivo BMP de 24 bits es una secuencia de bits, cada 24 de los cuales (bueno, casi) determinan el color de qué píxel. Además de los datos de color, un archivo BMP también contiene metadatos: información sobre el ancho y el alto de la imagen. Estos metadatos se almacenan al principio del archivo en forma de dos estructuras de datos comúnmente llamadas "encabezados" (que no deben confundirse con los archivos de encabezado C). El primero de estos encabezados es BITMAPFILEHEADER, que tiene una longitud de 14 bytes (o 14*8 bits). El segundo encabezado es BITMAPINFOHEADER (40 bytes de longitud). Después de estos encabezados viene el mapa de bits: una matriz de bytes, cuyos tripletes representan el color del píxel (1, 4 y 16 bits en BMP, pero no 24 o 32; tienen un encabezado adicional justo después de BITMAPINFOHEADER. Se llama la matriz RGBQUAD, que define el “valor de intensidad” para cada uno de los colores de la paleta). Sin embargo, BMP almacena estos tripletes al revés (podríamos decir como BGR), con 8 bits para azul, 8 bits para verde y 8 bits para rojo. Por cierto, algunos BMP también almacenan el mapa de bits completo al revés, comenzando desde la línea superior de la imagen al final del archivo BMP. En nuestra tarea, guardamos el VMR como se describe aquí, primero la fila superior de la imagen y luego las inferiores. En otras palabras, convertimos un emoji de un bit en uno de 24 bits reemplazando el negro por el rojo. Un BMP de 24 bits almacenará este mapa de bits, donde 0000ff representa el rojo y ffffff representa el blanco; Hemos resaltado todas las instancias de 0000ff en rojo. Harvard CS50: Tareas de la cuarta semana (Conferencias 9 y 10) - 4Como presentamos estos bits de izquierda a derecha y de arriba a abajo, puedes ver la carita sonriente roja en estas letras si te alejas un poco del monitor. Recuerde que un dígito en el sistema numérico hexadecimal representa 4 bits. En consecuencia, ffffff en hexadecimal en realidad significa 1111111111111111111111111 en binario. Ahora, disminuya la velocidad y no avance más hasta que esté seguro de comprender por qué 0000ff representa un píxel rojo en un archivo BMP de 24 bits. En la ventana CS50 IDE, expanda (por ejemplo, haciendo clic en el triángulo pequeño) la carpeta pset4 y en ella - bmp . En esta carpeta encontrará smiley.bmp , haga doble clic en el archivo y encontrará allí un pequeño emoticón de 8x8 píxeles. En el menú desplegable, cambie la escala de la imagen, digamos de 100% a 400%, esto le permitirá ver una versión más grande, pero al mismo tiempo más "borrosa", del emoticón. Aunque en realidad esta misma imagen no debería salir borrosa ni siquiera ampliada. Es solo que el IDE CS50 está tratando de hacerte un favor (al estilo de la serie CIA) suavizando la imagen (difuminando visualmente los bordes). Así quedará nuestro emoticón si lo ampliamos sin suavizar: Harvard CS50: Tareas de la cuarta semana (Conferencias 9 y 10) - 5Los píxeles se convirtieron en grandes cuadrados. Continuemos. En la terminal, vaya a ~/workspace/pset4/bmp . Creemos que ya recuerdas cómo hacer esto. Examinemos los bytes asignados en smiley.bmp . Esto se puede hacer usando el editor hexadecimal de línea de comando, el programa xxd . Para ejecutarlo, ejecute el comando: xxd -c 24 -g 3 -s 54 smiley.bmp Debería ver lo que se muestra a continuación; Hemos resaltado nuevamente en rojo todas las instancias de 0000ff. Harvard CS50: Tareas de la cuarta semana (Conferencias 9 y 10) - 6En la imagen de la columna de la izquierda puedes ver las direcciones del archivo, que equivalen al desplazamiento desde el primer byte del archivo. Todos ellos se dan en el sistema numérico hexadecimal. Si convertimos hexadecimal 00000036 a decimal, obtenemos 54. Entonces estás mirando el byte 54 de smiley.bmp . Recuerde que en los archivos BMP de 24 bits, los primeros 14 + 40 = 54 bytes están llenos de metadatos. Entonces, si desea ver los metadatos, ejecute el siguiente comando: xxd -c 24 -g 3 smiley.bmp Si smiley.bmp contiene caracteres ASCII , los veremos en la columna de la derecha en xxd en lugar de todos esos puntos. Entonces, Smiley es un BMP de 24 bits (cada píxel está representado por 24 ÷ 8 = 3 bytes) con un tamaño (resolución) de 8x8 píxeles. Cada línea (o "Scanline", como se la llama) ocupa (8 píxeles) x (3 bytes por píxel) = 24 bytes. Este número es múltiplo de cuatro, y esto es importante porque el archivo BMP se almacena de manera ligeramente diferente si el número de bytes en la línea no es múltiplo de cuatro. Entonces, en small.bmp, otro archivo BMP de 24 bits en nuestra carpeta, puede ver un cuadro verde de 3x3 píxeles. Si lo abres en un visor de imágenes, verás que se parece a la imagen que se muestra a continuación, sólo que de menor tamaño. Harvard CS50: Tareas de la cuarta semana (Conferencias 9 y 10) - 7Por lo tanto, cada línea en small.bmp ocupa (3 píxeles) × (3 bytes por píxel) = 9 bytes, que no es un múltiplo de 4. Para obtener una longitud de línea que sea múltiplo de 4, se rellena con ceros adicionales: entre 0 y 3 bytes completamos cada línea en formato BMP de 24 bits (¿puedes adivinar por qué?). Para small.bmp , se necesitan 3 bytes de ceros, ya que (3 píxeles) x (3 bytes por píxel) + (3 bytes de relleno) = 12 bytes, que en realidad es un múltiplo de 4. Para "ver" este relleno, Haz lo siguiente. xxd -c 12 -g 3 -s 54 small.bmp Tenga en cuenta que usamos un valor diferente para -c que con smiley.bmp , por lo que xxd solo genera 4 columnas esta vez (3 para el cuadrado verde y 1 para el relleno). Para mayor claridad, hemos resaltado todas las instancias de 00ff00 en verde. Harvard CS50: Tareas de la cuarta semana (Conferencias 9 y 10) - 8Por el contrario, usemos xxd para el archivo grande.bmp . Se ve exactamente igual que pequeño.bmp., sólo que su resolución es de 12x12 píxeles, es decir, cuatro veces mayor. Ejecute el siguiente comando. Es posible que tengas que ampliar la ventana para evitar la transferencia. xxd -c 36 -g 3 -s 54 large.bmp Verá algo como esto: ¡ Harvard CS50: Asignaciones de la Semana 4 (Conferencias 9 y 10) - 9Tenga en cuenta que no hay digresiones en este BMP! Después de todo, (12 píxeles) × (3 bytes por píxel) = 36 bytes, y esto es un múltiplo de 4. El editor hexadecimal xxd nos mostró los bytes en nuestros archivos BMP. ¿Cómo podemos obtenerlos mediante programación? En copy.c hay un programa cuyo único propósito en la vida es crear una copia del BMP, pieza por pieza. Sí, puedes usar cp para esto . Sin embargo, cp no podrá ayudar al Sr. Boddy. Esperemos que copy.c haga esto, así que allá vamos: ./copy smiley.bmp copy.bmp si ahora ejecuta ls (con el indicador apropiado), verá que smiley.bmp y copy.bmp son de hecho del mismo tamaño. Comprobemos nuevamente si esto es realmente cierto. diff smiley.bmp copy.bmp Si este comando no muestra nada en la pantalla, significa que los archivos son efectivamente idénticos (importante: algunos programas, como Photoshop, incluyen ceros finales al final de algunos VMP. Nuestra versión de copia los descarta, así que no Preocúpese si, en caso de copiar otros BMP que haya descargado o creado para realizar pruebas, la copia será unos pocos bytes más pequeña que el original). Puede abrir ambos archivos en el visor de imágenes de Ristretto (doble clic) para confirmarlo visualmente. Pero diff hace esta comparación byte a byte, por lo que su visión es más nítida que la tuya. ¿Cómo se creó esta copia? Resulta que copy.c está relacionado con bmp.h. Asegurémonos: abra bmp.h. Allí verá las definiciones reales de los encabezados que ya hemos mencionado, adaptadas de las propias implementaciones de Microsoft. Además, este archivo define los tipos de datos BYTE, DWORD, LONG y WORD, que son los tipos de datos que normalmente se encuentran en el mundo de la programación Win32 (es decir, Windows). Tenga en cuenta que estos son esencialmente alias de primitivas con las que (con suerte) ya está familiarizado. Resulta que BITMAPFILEHEADER y BITMAPINFOHEADER estaban usando estos tipos. Este archivo también define una estructura llamada RGBTRIPLE. “Encapsula” tres bytes: uno azul, uno verde y uno rojo (este es el orden en el que buscaremos tripletes RGB en el disco). ¿Cómo son útiles estas estructuras? En resumen, un archivo es simplemente una secuencia de bytes (o, en última instancia, bits) en el disco. Sin embargo, estos bytes normalmente están ordenados de modo que los primeros representen algo, luego los siguientes representen algo más, y así sucesivamente. Los "formatos" de archivos existen porque tenemos estándares o reglas que definen qué significan los bytes. Ahora, podemos simplemente leer el archivo del disco a la RAM como una gran matriz de bytes. Y recordemos que el byte en la posición [i] representa una cosa, mientras que el byte en la posición [j] es otra. Pero, ¿por qué no dar nombres a algunos de estos bytes para que podamos recuperarlos más fácilmente de la memoria? Esto es exactamente en lo que nos ayudan las estructuras en bmp.h. En lugar de pensar en un archivo como una larga secuencia de bytes, lo vemos dividido en bloques más comprensibles: secuencias de estructuras. Recuerde que smiley.bmp tiene una resolución de 8x8 píxeles, por lo que ocupa 14 + 40 + (8 × 8) × 3 = 246 bytes en el disco (puede verificar esto usando el comando ls). Así es como se ve en el disco según Microsoft: Harvard CS50: Tareas de la cuarta semana (Conferencias 9 y 10) - 10Podemos ver que el orden importa cuando se trata de miembros de estructuras. El byte 57 es rgbtBlue (no, digamos, rgbtRed) porque rgbtBlue se define primero en RGBTRIPLE. Por cierto, nuestro uso del atributo empaquetado garantiza que clang no intente “alinear palabras” a los miembros (con la dirección del primer byte de cada miembro siendo un múltiplo de 4), de modo que no terminemos con agujeros en nuestras estructuras que no existen en el disco en absoluto. Vamonos. Busque las URL que coincidan con BITMAPFILEHEADER y BITMAPINFOHEADER, según los comentarios en bmp.h. Atención, gran momento: ¡estás empezando a utilizar MSDN (Microsoft Developer Network)! En lugar de desplazarse más por copy.c , responda algunas preguntas para comprender cómo funciona el código. Como siempre, el comando man es tu verdadero amigo, y ahora también MSDN. Si no sabes las respuestas, busca en Google y piénsalo. También puede consultar el archivo stdio.h en https://reference.cs50.net/.
  1. Establezca un punto de interrupción en principal (haciendo clic a la izquierda de la regla con los números de línea principal).

  2. En una pestaña de terminal , vaya a ~/workspace/pset4/bmp y compile copy.c en el programa de copia usando make.

  3. Ejecute debug50 copy smiley.bmp copy.bmp , esto abrirá el panel del depurador a la derecha.

  4. Recorre el programa paso a paso utilizando el panel de la derecha. Nota bf y bi . En ~/workspace/pset4/questions.txt , responda las preguntas:

  • ¿ Qué es stdint.h ?

  • ¿Cuál es el punto de usar uint8_t , uint32_t , int32_t y uint16_t en un programa?

  • ¿Cuántos bytes contienen BYTE , DWORD , LONG y WORD respectivamente (suponiendo una arquitectura de 32 bits)?

  • ¿Cuáles (ASCII, decimal o hexadecimal) deben ser los primeros dos bytes de un archivo BMP? (Los bytes iniciales, que se utilizan para identificar el formato del archivo (con alta probabilidad) a menudo se denominan "números mágicos").
  • ¿Cuál es la diferencia entre bfSize y biSize?

  • ¿Qué significa una biHeight negativa?

  • ¿Qué campo en BITMAPINFOHEADER define la profundidad de color en BMP (es decir, bits por píxel)?

  • ¿Por qué la función fopen puede devolver NULL en copy.c 37?

  • ¿Por qué el tercer argumento de fread en nuestro código es igual a 1?

  • ¿Qué valor en copy.c 70 define el relleno si bi.biWidth es 3?

  • ¿Qué hace fseek?

  • ¿Qué es SEEK_CUR?

Volvamos al Sr. Boddy. Ejercicio:

Escribe un programa llamado whodunit en un archivo llamado whodunit.c que muestre el dibujo del Sr. Boddy. Mmmmm, ¿qué? Al igual que copiar, el programa debe tomar exactamente dos argumentos de línea de comando, y si ejecuta su programa como se muestra a continuación, el resultado se almacenará en verdict.bmp, en el que el dibujo del Sr. Boddy no será ruidoso. ./whodunit clue.bmp verdict.b Le sugerimos que comience a resolver este misterio ejecutando el siguiente comando. cp copy.c whodunit.c Es posible que se sorprenda de cuántas líneas de código necesita escribir para ayudar al Sr. Boddy. No hay nada innecesario oculto en smiley.bmp , así que siéntete libre de probar el programa en este archivo. Es pequeño y puede comparar el resultado de su programa y el resultado de xxd durante el desarrollo (¿o tal vez hay algo oculto en smiley.bmp ? En realidad, no). Por cierto, este problema se puede solucionar de diferentes formas. Una vez que identifiques el dibujo del Sr. Boddy, descansará en paz. Dado que whodunit se puede implementar de varias maneras, no podrá verificar la exactitud de las implementaciones con check50 . Y deja que eso arruine tu diversión, pero la solución de los asistentes tampoco está disponible para el problema de la novela policíaca . Finalmente, en el archivo In ~/workspace/pset4/questions.txt , responda la siguiente pregunta: Whodunit? //ктоэтосделал?

cambiar el tamaño

Bueno, ahora, ¡la próxima prueba! Escribamos un programa llamado cambiar tamaño en resize.c . Cambiará el tamaño de una imagen BMP de 24 bits sin comprimir en pasos de n. Su aplicación debe aceptar exactamente tres argumentos de línea de comando, siendo el primero (n) un número entero no mayor a 100, el segundo el nombre del archivo que se modificará y el tercero el nombre de la versión guardada del archivo modificado. archivo. Usage: ./resize n infile outfile Con un programa de este tipo, podríamos crear un archivo grande.bmp a partir de un archivo pequeño.bmp cambiando el tamaño de este último por 4 (es decir, multiplicando el ancho y el alto por 4), como se muestra a continuación. Para simplificar, puede iniciar la tarea copiando copy.c./resize 4 small.bmp large.bmp nuevamente y nombrando la copia resize.c . Pero primero, pregúntese y responda estas preguntas: ¿qué significa cambiar el tamaño de BMP (puede asumir que n veces el tamaño del archivo no excederá 232 - 1) ? Determine qué campos en BITMAPFILEHEADER y BITMAPINFOHEADER necesita cambiar. Considere si necesita agregar o eliminar campos de líneas de exploración . Y sí, ¡agradezca que no le pedimos que considere todos los valores posibles de n de 0 a 1! (aunque, si estás interesado, este es un problema sacado de un libro de hackers;)). Sin embargo, asumimos que para n = 1 el programa funcionará correctamente y el archivo de salida tendrá el mismo tamaño que el archivo de entrada original. ¿Quieres comprobar el programa usando check50? Escriba el siguiente comando: check50 2015.fall.pset4.resize bmp.h resize.c ¿Quieres jugar con la implementación de la aplicación realizada por los asistentes de CS50? Ejecute lo siguiente: ~cs50/pset4/resize Bueno, si desea ver, por ejemplo, los encabezados grandes.bmp (en una forma más fácil de usar que la que permite xxd), debe ejecutar el siguiente comando: ~cs50/pset4/peek large.bmp Aún mejor, si desea comparar sus encabezados con los encabezados de los archivos del asistente CS50. Puede ejecutar comandos dentro de su directorio ~/workspace/pset4/bmp (piense en lo que hace cada comando). Si usó malloc , asegúrese de usar free para evitar pérdidas de memoria. Intente usar valgrind para comprobar si hay fugas. ./resize 4 small.bmp student.bmp
~cs50/pset4/resize 4 small.bmp staff.bmp
~cs50/pset4/peek student.bmp staff.bmp

¿Cómo decidir?

  • Abra el archivo que necesitamos ampliar, y también cree y abra un nuevo archivo en el que se grabará la imagen ampliada;

  • actualizar la información del encabezado del archivo de salida. Como nuestra imagen está en formato BMP y estamos cambiando su tamaño, necesitamos escribir el encabezado del nuevo archivo con las nuevas dimensiones. ¿Qué cambiará? El tamaño del archivo, así como el tamaño de la imagen: su ancho y alto.

Harvard CS50: Tareas de la cuarta semana (Conferencias 9 y 10) - 11Si miramos la descripción del encabezado, veremos la variable biSizeImage . Indica el tamaño total de la imagen en bytes, biWidth es el ancho de la imagen menos la alineación, biHeight es la altura. Estas variables se encuentran en las estructuras BITMAPFILEHEADER y BITMAPINFOHEADER. Puede encontrarlos si abre el archivo bmp.h. Harvard CS50: Tareas de la cuarta semana (Conferencias 9 y 10) - 12La descripción de la estructura BITMAPINFOHEADER contiene una lista de variables. Para escribir el título del archivo de salida, deberá cambiar los valores de alto y ancho. Pero también existe la posibilidad de que más adelante necesites la altura y el ancho originales del archivo original. Por tanto, es mejor conservar ambos. Tenga cuidado con los nombres de las variables para no escribir accidentalmente datos erróneos en el encabezado del archivo de salida.
  • Leemos el archivo saliente, línea por línea, píxel por píxel. Para hacer esto, volvemos a nuestra biblioteca de E/S de archivos y a la función fread. Toma un puntero a una estructura que contendrá los bytes leídos, el tamaño del elemento único que vamos a leer, el número de dichos elementos y un puntero al archivo desde el cual leeremos.

    Harvard CS50: Tareas de la cuarta semana (Conferencias 9 y 10) - 13
  • Aumentamos cada línea horizontalmente de acuerdo con la escala especificada y escribimos el resultado en el archivo de salida.

    Harvard CS50: Tareas de la cuarta semana (Conferencias 9 y 10) - 14

    ¿Cómo escribimos archivos? Tenemos una función fwrite, a la que le pasamos un indicador de la estructura donde se encuentran los datos a escribir en el archivo, el tamaño del elemento, su número y un puntero al archivo de salida. Para organizar el bucle, podemos utilizar el bucle for con el que ya estamos familiarizados .

    Harvard CS50: Tareas de la cuarta semana (Conferencias 9 y 10) - 15
  • ¡Rellena los huecos! Si el número de píxeles en una línea no es múltiplo de cuatro, debemos agregar "alineación": cero bytes. Necesitaremos una fórmula para calcular el tamaño de alineación. Para escribir bytes nulos en un archivo de salida, puede usar la función fputc, pasándole el carácter que desea escribir y un puntero al archivo de salida.

    Harvard CS50: Tareas de la cuarta semana (Conferencias 9 y 10) - 16

    Ahora que estiramos la cadena horizontalmente y agregamos una alineación al archivo de salida, necesitamos mover la posición actual en el archivo de salida porque necesitamos saltar sobre la alineación.

    Harvard CS50: Tareas de la cuarta semana (Conferencias 9 y 10) - 17
  • Aumentar el tamaño vertical. Es más complicado, pero podemos usar el código de muestra de copy.c (copy.c abre el archivo de salida, escribe un encabezado en el archivo de salida, lee la imagen del archivo fuente línea por línea, píxel por píxel y los escribe al archivo de salida). En base a esto, lo primero que puedes hacer es ejecutar el siguiente comando: cp copy.c resize.c

    Estirar una imagen verticalmente significa copiar cada línea varias veces. Hay varias formas diferentes de hacer esto. Por ejemplo, usando la reescritura, cuando guardamos todos los píxeles de una línea en la memoria y escribimos esta línea en el archivo de salida en un bucle tantas veces como sea necesario. Otro método es volver a copiar: después de leer una línea del archivo saliente, escribirla en el archivo de salida y alinearla, devolver la función fseek al principio de la línea en el archivo saliente y repetir todo varias veces.

    Harvard CS50: Asignaciones de la Semana 4 (Conferencias 9 y 10) - 18
  • recuperar

    Anticipándome al artículo problemático de la Semana 4, he pasado los últimos días mirando fotografías guardadas en formato JPEG con mi cámara digital en una tarjeta de memoria CompactFlash (CF) de 1 GB. Por favor, no me digas que en realidad he pasado los últimos días en Facebook. Desafortunadamente, mis habilidades informáticas dejan mucho que desear y, sin saberlo, ¡borré accidentalmente todas las fotos! Afortunadamente, en el mundo de la informática, "eliminado" normalmente no equivale a "eliminado". Mi computadora insiste en que la tarjeta de memoria ahora está vacía, pero sé que miente. Tarea: escriba un programa en ~/workspace/pset4/jpg/recover.c que recupere estas fotos. Mmm. Bien, aquí hay una aclaración más. Aunque el formato JPEG es más complejo que BMP, JPEG tiene "firmas", patrones de bytes que ayudan a distinguirlo de otros formatos de archivo. La mayoría de los archivos JPEG comienzan con los siguientes tres bytes: 0xff 0xd8 0xff del primer byte al tercero, de izquierda a derecha. Lo más probable es que el cuarto byte sea una de las siguientes combinaciones: 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,0xe8, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef. En otras palabras, los primeros cuatro bits del cuarto byte de un archivo JPEG son 1110. Lo más probable es que, si encuentra uno de estos patrones en la unidad donde se almacenaron las fotos (como mi tarjeta de memoria), este sea el comienzo del archivo JPEG. Por supuesto, esto se puede encontrar en qué disco por pura casualidad; la recuperación de datos no se puede llamar una ciencia exacta.

    como decidir

    1. Abra el archivo con el contenido de la tarjeta de memoria.

    2. Busque el comienzo del archivo JPEG. Todos los archivos de esta tarjeta son imágenes en formato JPEG.

    Ya conoce los marcadores JPEG: Harvard CS50: Tareas de la cuarta semana (Conferencias 9 y 10) - 19es importante (y bueno) saber que cada archivo JPEG se almacena en la memoria como un solo bloque y que los archivos se suceden uno tras otro. Dibujemos un mapa de memoria esquemático. Cada rectángulo es un bloque de 512 bytes de longitud. Los rectángulos grises son áreas donde no hay archivos JPEG; los asteriscos indican el comienzo del archivo JPEG. Creemos que no tenemos bloques grises entre archivos. Harvard CS50: Tareas de la cuarta semana (Conferencias 9 y 10) - 20¿Cómo leemos estos datos, estos 512 bytes, para comparar el comienzo con el encabezado JPEG? Podemos usar la función fread , que ya conocemos, que toma un puntero a la estructura de datos donde se escribirán los bytes leídos, así como el tamaño del elemento que se está leyendo, el número de dichos elementos, y un puntero al archivo desde el que estamos leyendo los datos. Harvard CS50: Tareas de la cuarta semana (Conferencias 9 y 10) - 21Queremos leer 512 bytes y almacenarlos en un búfer. Este será el puntero &data y el puntero inptr apuntará al archivo abierto con el contenido de la tarjeta de memoria. Entonces, volvamos a la estructura de nuestro archivo, en el que guardamos
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION