Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Coloboración Paypal con ClubDelphi

 
 
Herramientas Buscar en Tema Desplegado
  #12  
Antiguo 23-05-2006
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 26
seoane Va por buen camino
Lo de no comentar el codigo es una fea costumbre que tengo, pero estoy encantado de comentarlo si esta interesado. Para no volver a subir el proyecto voy a ir poniendo aqui varias de las funciones ya comentadas:


Estas funciones manejan el archivo JPEG una vez lo tenemos en un stream
Código Delphi [-]
// Esta funcion lee el comentario de un archivo JPEG.
// El archivo JPEG esta dividido en segmentos con el siguiente formato
// Identificador (2Bytes) + Longitud (2Bytes) + Contenido
// Asi que vamos leyendo segmento a segmento hasta encontrar el que nos interesa
function LeerCom(Stream: TStream): string;
var
  Buffer: array[0..$FFFF] of Char;
  Header: array[1..4] of byte;
  Size: Integer;
begin
  // Nos colocamos al principio del archivo
  Stream.Seek(0,soFromBeginning);
  // Leemos los 2 primeros Bytes
  Stream.ReadBuffer(Header,2);
  // Y comprobamos que son correctos  (todos los JPEG empiezan por FF D8)
  if (Header[1] <> $FF) or (Header[2] <> $D8) then
    // Si no es asi, provocamos un error
    raise Exception.Create('Identificador incorrecto');
  repeat
    // Leemos los 4 primeros bytes del segemento
    Stream.ReadBuffer(Header,4);
    // Usamos los 2 ultimos bytes para calcular el tamño del segmento
    // que es igual al tamaño del contenido + 2, asi que le restamos 2
    Size:= ((Header[3] shl 8) + Header[4]) - 2;
    // Todos los segmentos comienzan por FF asi que utilizamos el segundo
    // byte para identificarlos
    case Header[2] of
      // FE corresponde al segemnto con los comentarios
      $FE: begin
             FillChar(Buffer,Sizeof(Buffer),0);
             // Leemos el contenido del segemento
             Stream.ReadBuffer(Buffer,Size);
             // Y lo convertimos en un string
             Result:= String(PChar(@Buffer));
           end;
      // Estos segemntos son casos especiales, solo miden 2 bytes, asi que
      // restrocedemos el puntero 2 bytes hacia atras
      $01,$D0..$D9: Stream.Seek(-2,soFromCurrent) ;
      // Si no es ni un comentario ni un caso especial, adelantamos el puntero
      // hasta el siguiente segmento
      else Stream.Seek(Size,soFromCurrent);
    end;
  // Salimos del bucle si ya hemos leido el comentario o llegamos al ultimo
  // segmento, ya que a partir de aqui el archivo solo contiene informacion
  // correspondiente a la propia imagen.
  until (Result <> '') or (Header[2] = $DA);
end;

// Esta funcion inserta un comentario. Hay que tener en cuenta que si hay un
// comentario anterior no se elimina, asi que deberemos usar antes la
// funcion "Limpiar" para quitar los comentarios anteriores.
procedure InsertarCom(Origen, Destino: TStream; Comment: string);
var
  Buffer: array[0..$FFFF] of Char;
  Header: array[1..4] of byte;
  Size: Integer;
begin
  // No colocamos al principio del archivo
  Origen.Seek(0,soFromBeginning);
  // Leemos los 2 primeros bytes
  Origen.ReadBuffer(Header,2);
  // y comprobamos que son correctos
  if (Header[1] <> $FF) or (Header[2] <> $D8) then
    raise Exception.Create('Identificador incorrecto');
  // Escribimos los 2 primeros bytes
  Destino.WriteBuffer(Header,2);
  // Calculamos la longitud del segmento
  Size:= Length(Comment) + 2;
  Header[1]:= $FF;
  Header[2]:= $FE;
  Header[3]:= Size div 256;
  Header[4]:= Size mod 256;
  // Copiamos el comentario a un buffer
  StrCopy(@Buffer,PChar(Comment));
  // Escribimos la cabecera del segmento
  Destino.WriteBuffer(Header,4);
  // Escribimos el contenido del segmento
  Destino.WriteBuffer(Buffer,Length(Comment));
  // Copiamos el resto
  Destino.CopyFrom(Origen,Origen.Size - Origen.Position);
end;

// Esta funcion elimina los segmentos resrvados para comentarios y para
// aplicaciones, informacion que nos es necesaria para ver la imagen. Hay
// que tener cuidado porque algunas aplicaciones guardan informacion ahi, por
// ejemplo cuando fue tomada la foto o que camara se uso.
procedure Limpiar(Origen, Destino: TStream);
var
  Buffer: array[0..$FFFF] of Char;
  Header: array[1..4] of byte;
  Size: Integer;
begin
  // Nos colocamos al principio del archivo
  Origen.Seek(0,soFromBeginning);
  // Leemos los 2 primeros bytes
  Origen.ReadBuffer(Header,2);
  // Comprobamos que son correctos
  if (Header[1] <> $FF) or (Header[2] <> $D8) then
    raise Exception.Create('Identificador incorrecto');
  Destino.WriteBuffer(Header,2);
  // Leemos segemento a segmento
  repeat
    Origen.ReadBuffer(Header,4);
    Size:= ((Header[3] shl 8) + Header[4]) - 2;
    case Header[2] of
      // Si es un comentario o un segmento de aplicacion saltamos al siguiente
      $FE, $E0..$EF: Origen.Seek(Size,soFromCurrent);
      // Si es un caso especial retrocedemos 2 bytes
      $01,$D0..$D9: begin
                      Destino.WriteBuffer(Header,2);
                      Origen.Seek(-2,soFromCurrent)
                    end
      else
      // Si es un segmento normal lo copiamos
      begin
        Origen.ReadBuffer(Buffer,Size);
        Destino.WriteBuffer(Header,4);
        Destino.WriteBuffer(Buffer,Size);
      end;
    end;
  until Header[2] = $DA;
  // Copiamos el resto del archivo
  Destino.CopyFrom(Origen,Origen.Size - Origen.Position);
end;

Para mas informacion sobre el formato de archivo JPEG
http://www.wotsit.org/search.asp?page=5&s=graphics

PD: Al comentar la funcion de insertar comentario me di cuenta de que daba mas pasos de los necesarios, debido a una confusion que tenia con respecto al primer segmento. Esto demuestra que nunca esta mal repasar el codigo

Última edición por seoane fecha: 23-05-2006 a las 20:35:31.
Responder Con Cita
 


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Programa PDA. Aprendiendo Varios 1 11-01-2005 18:17:23
Lanzar programa desde mi programa Pablo Carlos API de Windows 32 09-09-2004 13:56:26
Ejecutar un programa externo desde un programa de Delphi Roger_Fernandez Varios 3 02-09-2004 18:05:36
programa c++ tartinamb C++ Builder 5 23-04-2004 17:01:24
Ejecutar un programa DENTRO de otro programa seduerey Varios 8 12-11-2003 13:56:20


La franja horaria es GMT +2. Ahora son las 20:46:06.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi