Libpng-Version 1.2.5

Von: R. Krüger

  |   29.08.09
Home > Server Administration

Eine Beschreibung dafür, wie man libpng verwendet und modifiziert

Libpng-Version 1.2.5 - am 2. Oktober 2002
Aktualisiert und verteilt von Glenn Randers-Pehrson <glennrp@users.sf.net>
Copyright (c) 1998-2002 Glenn Randers-Pehrson
Für Bedingungen des Vertriebs und Gebrauches, sieh Urheberrechtsvermerk in png.h.

beruhend auf:

libpng 1.0 Version 0.96 des Betas 6 am 28. Mai 1997
Aktualisiert und verteilt von Andreas Dilger
Copyright (c) 1996, 1997 Andreas Dilger

libpng 1.0 Beta 2 - Version 0.88 am 26. Januar 1996
Für Bedingungen des Vertriebs und Gebrauches, sieh Urheberrechtsvermerk in png.h.
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.

Aktualisiert/umgeschrieben auf Anfrage in den libpng "häufig gestellten Fragen"
Copyright (c) 1995, 1996 Frank J. T. Wojcik
Am 18. Dezember 1995 & am 20. Januar 1996



I. Einführung

Diese Datei beschreibt, wie man verwendet und die PNG Präsenzbibliothek (bekannt als libpng) für Ihren eigenen Gebrauch modifiziert. Es gibt fünf Abteilungen zu dieser Datei: Einführung, Strukturen, das Lesen, das Schreiben, und die Modifizierung und die Konfiguration bemerken für verschiedene spezielle Plattformen. Zusätzlich zu dieser Datei ist example.c ein guter Startpunkt, um die Bibliothek zu verwenden, weil es schwer kommentiert wird und alles umfassen sollte, was die meisten Menschen brauchen werden. Wir nehmen an, dass libpng bereits installiert wird; sieh die INSTALLIEREN Datei für Instruktionen darauf, wie man libpng installiert.

Libpng wurde als ein Begleiter zur PNG Spezifizierung als eine Weise geschrieben, die Zeitdauer und Anstrengung zu reduzieren, die es bringt, um das PNG Dateiformat in Anwenderprogrammen zu unterstützen.

Die PNG-1.2 Spezifizierung ist an <http://www.libpng.org/pub/png> und an <ftp://ftp.uu.net/graphics/png/documents/> verfügbar.

Die PNG-1.0 Spezifizierung ist als RFC 2083 <ftp://ftp.uu.net/graphics/png/documents/> und als eine W3C Empfehlung <http://www.w3.org/TR/REC.png.html> verfügbar. Einige zusätzliche Klötze werden in den Publikum-Klotz-Dokumenten des speziellen Zwecks an <ftp://ftp.uu.net/graphics/png/documents/> beschrieben.

Andere Information über PNG, und die letzte Version von libpng, können an der PNG Einstiegsseite, <http://www.libpng.org/pub/png/> und an <ftp://ftp.uu.net/graphics/png/> gefunden werden.

Die meisten Benutzer werden die Bibliothek bedeutsam nicht modifizieren müssen; fortgeschrittene Benutzer können es mehr modifizieren wollen. Alle Versuche wurden gemacht, es ebenso abgeschlossen wie möglich zu machen, indem sie den Code behielten, der leicht ist zu verstehen. Zurzeit wird diese Bibliothek nur Supports C. Support für andere Sprachen betrachtet.

Libpng ist entworfen worden, um vielfache Sitzungen auf einmal zu behandeln, leicht modifizierbar zu sein, zur großen Mehrheit von Maschinen (ANSI, K&R, 16-, 32-, und 64 Bit) verfügbar tragbar zu sein, und leicht zu sein, zu verwenden. Die äußerste Absicht von libpng ist, die Annahme des PNG Dateiformats auf beliebige mögliche Weise zu fördern. Während es noch zu tuende Arbeit gibt (sieh die TODO Datei), sollte libpng die Mehrheit der Bedürfnisse nach seinen Benutzern bedecken.

Libpng verwendet zlib für seine Kompression und Dekompression von PNG Dateien. Weitere Information über zlib, und die letzte Version von zlib, können an der zlib Einstiegsseite, <http://www.info-zip.org/pub/infozip/zlib/> gefunden werden. Das zlib Kompressionsdienstprogramm ist ein allgemeines Zweck-Dienstprogramm, das für mehr nützlich ist als PNG Dateien, und ohne libpng verwendet werden kann. Sieh die Dokumentation, die mit zlib für mehr Details geliefert ist. Sie können gewöhnlich die Ursprungsdateien für das zlib Dienstprogramm finden, wo auch immer Sie die libpng Ursprungsdateien finden.

Libpng ist Faden-Safe, vorausgesetzt dass die Fäden verschiedene Beispiele der Strukturen verwenden. Jeder Faden sollte seinen eigenen png_struct und png_info Beispiele, und so sein eigenes Image haben. Libpng schützt sich gegen zwei Fäden nicht, denselben Beispiel einer Struktur verwendend. Bemerken Sie: Faden-Sicherheit kann durch den Gebrauch von etwas vom MMX Assemblercode in pnggccrd.c vereitelt werden, der nur kompiliert wird, wenn der Benutzer PNG_THREAD_UNSAFE_OK definiert.

II. Strukturen

Es gibt zwei Hauptstrukturen, die für libpng, png_struct und png_info wichtig sind. Das erste, png_struct, ist eine interne Struktur, die größtenteils von einem Benutzer außer nicht verwendet wird, weil die erste Variable zu jedem libpng Funktionsaufruf ging.

Die png_info Struktur wird entworfen, um Auskunft über die PNG Datei zu geben. Auf einmal waren die Felder von png_info beabsichtigt, um für den Benutzer direkt zugänglich zu sein. Jedoch neigte das dazu, Probleme mit Anwendungen zu verursachen, die dynamisch geladene Bibliotheken verwenden, und infolgedessen wurde eine Reihe von Schnittstelle-Funktionen für png_info (der png_get_ * () und png_set_ * () Funktionen) entwickelt. Die Felder von png_info sind noch für ältere Anwendungen verfügbar, aber es wird darauf hingewiesen, dass Anwendungen die neuen Schnittstellen wenn überhaupt möglich verwenden.

Anwendungen, die wirklich direkten Zugriff den Mitgliedern von png_struct machen (abgesehen von png_ptr-> jmpbuf) müssen wiederkompiliert werden, wann auch immer die Bibliothek aktualisiert wird, und Anwendungen, die direkten Zugriff den Mitgliedern von png_info machen, wiederkompiliert werden müssen, wenn sie kompiliert oder mit der libpng Version 1.0.6 geladen wurden, in der die Mitglieder in einer verschiedenen Ordnung waren. In der Version 1.0.7 kehrten die Mitglieder der png_info Struktur zur alten Ordnung zurück, weil sie in Versionen 0.97c bis 1.0.5 waren. Mit der Version 2.0.0 anfangend, sind beide Strukturen dabei, verborgen zu werden, und der Inhalt der Strukturen wird nur durch die png_get/png_Set-Funktionen zugänglich sein.

Die png.h Kopfball-Datei ist eine unschätzbare Verweisung, um mit libpng zu programmieren. Und während ich zum Thema bin, stellen Sie sicher, dass Sie die libpng Kopfball-Datei umfassen:

   #include <png.h> 

III. Das Lesen

Wir werden Sie jetzt durch die möglichen Funktionen spazieren gehen zu rufen, indem wir in einer PNG Datei folgend kurz lesen werden, die Syntax und den Zweck von jedem erklärend. Sieh example.c und png.h für mehr Detail. Während das progressive Lesen in der folgenden Abteilung bedeckt wird, werden Sie noch einige der in dieser Abteilung besprochenen Funktionen brauchen, um eine PNG Datei zu lesen.

Einstellung

Sie werden die Eingabe/Ausgabe-Initialisierung (*) tun wollen, bevor Sie in libpng so kommen, wenn es nicht arbeitet, haben Sie viel nicht, um aufzumachen. Natürlich werden Sie auch versichern wollen, dass Sie SICH tatsächlich mit einer PNG Datei befassen. Libpng stellt eine einfache Kontrolle zur Verfügung, um zu sehen, ob eine Datei eine PNG Datei ist. Um es zu verwenden, gehen Sie in den ersten 1 bis 8 Bytes der Datei zur Funktion png_sig_cmp (), und es wird 0 zurückkehren, wenn die Bytes die entsprechenden Bytes der PNG Unterschrift, oder Nichtnull in anderer Weise vergleichen. Natürlich, je mehr Bytes Sie in, desto größer die Genauigkeit der Vorhersage gehen.

Wenn Sie vorhaben, den Dateiadressenverweis offen für den Gebrauch in libpng zu halten, müssen Sie sicherstellen, dass Sie mehr als 8 Bytes vom Anfang der Datei nicht lesen, und Sie auch einen Anruf png_set_sig_bytes_read () mit der Anzahl von Bytes machen müssen, die Sie vom Anfang lesen. Libpng wird dann nur die Bytes überprüfen (wenn irgendwelcher), den Ihr Programm nicht las.

(*): Wenn Sie die Standardeingabe/Ausgabe-Funktionen nicht verwenden, werden Sie sie durch kundenspezifische Funktionen ersetzen müssen. Sieh die Diskussion unter der Anpassung libpng.

 
    FILE *fp = fopen(file_name, "rb");
    if (!fp)
    {
        return (ERROR);
    }
    fread(header, 1, number, fp);
    is_png = !png_sig_cmp(header, 0, number);
    if (!is_png)
    {
        return (NOT_PNG);
    }

Dann müssen png_struct und png_info alloziert und initialisiert werden. Um sicherzustellen, dass die Größe dieser Strukturen sogar mit einem dynamisch verbundenen libpng richtig ist, gibt es Funktionen, die Strukturen zu initialisieren und zu allozieren. Wir passieren auch die Bibliotheksversion, optionalen Adressenverweise zu Fehlerbehandlungsfunktionen, und einen Adressenverweis zu Daten struct für den Gebrauch durch die Fehlerfunktionen nötigenfalls (der Adressenverweis, und Funktionen können UNGÜLTIG sein, wenn die Verzug-Fehlerbehandlungsprogramme verwendet werden sollen). Sieh die Abteilung auf Änderungen zu Libpng unter der Bewertung der alten Initialisierungsfunktionen. Die Struktur-Allozierungsfunktionen kehren ruhig UNGÜLTIG zurück, wenn sie scheitern, die Struktur zu schaffen, so sollte Ihre Anwendung dafür überprüfen.

     png_structp png_ptr = png_create_read_struct
       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
        user_error_fn, user_warning_fn);
    if (!png_ptr)
        return (ERROR);

    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr)
    {
        png_destroy_read_struct(&png_ptr,
           (png_infopp)NULL, (png_infopp)NULL);
        return (ERROR);
    }

    png_infop end_info = png_create_info_struct(png_ptr);
    if (!end_info)
    {
        png_destroy_read_struct(&png_ptr, &info_ptr,
          (png_infopp)NULL);
        return (ERROR);
    }

Wenn Sie Ihre eigenen Arbeitsspeicherzuweisungsroutinen verwenden wollen, PNG_USER_MEM_SUPPORTED zu definieren und png_create_read_struct_2 () statt png_create_read_struct () zu verwenden:

 png_structp png_ptr = png_create_read_struct_2
       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
        user_error_fn, user_warning_fn, (png_voidp)
        user_mem_ptr, user_malloc_fn, user_free_fn);

Die Fehlerbehandlungsroutinen gingen zu png_create_read_struct (), und der Speicher alloc/free Routinen ging zu png_create_struct_2 () sind nur notwendig, wenn Sie gelieferte Fehlerbehandlung des libpng und Speicher alloc/free Funktionen nicht verwenden.

Wenn libpng auf einen Fehler stößt, erwartet er zu longjmp zurück zu Ihrer Routine. Deshalb werden Sie setjmp nennen und Ihren png_jmpbuf (png_ptr) passieren müssen. Wenn Sie die Datei von verschiedenen Routinen lesen, werden Sie das jmpbuf Feld jedes Mal aktualisieren müssen, wenn Sie eine neue Routine eingeben, die einen png_ * () Funktion nennen wird.

Sieh Ihre Dokumentation von setjmp/longjmp für Ihren Bearbeiter für weitere Informationen über setjmp/longjmp. Sieh die Diskussion über die libpng Fehlerbehandlung in der Anpassung Libpng Abteilung unten für weitere Informationen über die libpng Fehlerbehandlung. Wenn ein Fehler, und libpng longjmp's zurück zu Ihrem setjmp vorkommt, werden Sie png_destroy_read_struct () nennen wollen, um jeden Speicher zu befreien.

    if (setjmp(png_jmpbuf(png_ptr)))
    {
        png_destroy_read_struct(&png_ptr, &info_ptr,
           &end_info);
        fclose(fp);
        return (ERROR);

Wenn Sie die Kompliziertheit von setjmp/Longjmp-Problemen lieber vermeiden möchten, können Sie libpng mit PNG_SETJMP_NOT_SUPPORTED kompilieren, in welchem Fall Fehler auf einen Anruf zu PNG_ABORT () welch Verzug hinauslaufen werden () abzubrechen.

Jetzt müssen Sie den Eingangscode aufstellen. Der Verzug für libpng soll die C-Funktion fread () verwenden. Wenn Sie das verwenden, werden Sie eine gültige DATEI * in der Funktion png_init_io () passieren müssen. Seien Sie überzeugt, dass die Datei in der binären Weise geöffnet wird. Wenn Sie Lesen-Daten auf eine andere Weise behandeln möchten, brauchen Sie nicht den png_init_io () Funktion zu nennen, aber Sie müssen dann die libpng Eingabe/Ausgabe-Methoden durchführen, die in der Anpassung Libpng Abteilung unten besprochen sind.

    png_init_io(png_ptr, fp);

Wenn Sie vorher die Datei geöffnet und einige der Unterschrift vom Anfang gelesen hatten, um zu sehen, ob das eine PNG Datei war, müssen Sie libpng mitteilen, dass es einige Bytes gibt, die vom Anfang der Datei fehlen.

        png_set_sig_bytes(png_ptr, number);

Aufstellung des Rückrufaktionscodes

Sie können eine Rückrufaktionsfunktion aufstellen, irgendwelche unbekannten Klötze im Eingabedatenstrom zu behandeln. Sie müssen die Funktion liefern

  read_chunk_callback(png_ptr ptr,
         png_unknown_chunkp chunk);
    {
       /* The unknown chunk structure contains your
          chunk data: */
           png_byte name[5];
           png_byte *data;
           png_size_t size;
       /* Note that libpng has already taken care of
          the CRC handling */

       /* put your code here.  Return one of the
          following: */

       return (-n); /* chunk had an error */
       return (0); /* did not recognize */
       return (n); /* success */
    }

(Sie können Ihrer Funktion einen anderen Namen geben, den Sie statt "read_chunk_callback" mögen)

Um libpng über Ihre Funktion zu informieren, verwenden

    png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr,
        read_chunk_callback);
 

Das nennt nicht nur die Rückrufaktionsfunktion, sondern auch einen Benutzeradressenverweis, mit dem Sie abrufen können

    png_get_user_chunk_ptr(png_ptr);

An diesem Punkt können Sie eine Rückrufaktionsfunktion aufstellen, die genannt wird, nachdem jede Reihe gelesen worden ist, den Sie verwenden können, um einen Fortschritt-Meter oder das ähnliche zu kontrollieren. Es wird in pngtest.c demonstriert. Sie müssen eine Funktion liefern

    void read_row_callback(png_ptr ptr, png_uint_32 row,
       int pass);
    {
      /* put your code here */
    }

(Sie können ihm einen anderen Namen geben, den Sie statt "read_row_callback" mögen)

Um libpng über Ihre Funktion zu informieren, verwenden

       png_set_read_status_fn(png_ptr, read_row_callback);

Das Berühren des unbekannten Klotzes

Jetzt kommen Sie, um den Weg zu setzen, wie die Bibliothek unbekannte Klötze im Eingang PNG Strom bearbeitet. Sowohl bekannte als auch unbekannte Klötze werden gelesen. Normales Verhalten besteht darin, dass bekannte Klötze in die Information in verschiedenen info_ptr Mitgliedern grammatisch analysiert werden; unbekannte Klötze werden verworfen. Um das zu ändern, können Sie rufen:

    png_set_keep_unknown_chunks(png_ptr, info_ptr, keep,
        chunk_list, num_chunks);
    keep       - 0: do not keep
                 1: keep only if safe-to-copy
                 2: keep even if unsafe-to-copy
    chunk_list - list of chunks affected (a byte string,
                 five bytes per chunk, NULL or '\0' if
                 num_chunks is 0)
    num_chunks - number of chunks affected; if 0, all
                 unknown chunks are affected

Unbekannte Klötze erklärt werden auf diese Weise als Ausgangsdaten auf eine Liste von png_unknown_chunk Strukturen gespeichert. Wenn ein Klotz, der normalerweise zu libpng bekannt ist, in der Liste genannt wird, wird es als unbekannt gemäß der "behalten" Direktive behandelt. Wenn ein Klotz in aufeinander folgenden Beispielen von png_set_keep_unknown_chunks genannt wird (), wird der Endbeispiel den Vortritt haben.

Die gelesene Schnittstelle auf höchster Ebene

An diesem Punkt gibt es zwei Wege weiterzugehen; durch die gelesene Schnittstelle auf höchster Ebene, oder durch eine Folge von auf niedriger Stufe Lesevorgängen. Sie können die Schnittstelle auf höchster Ebene verwenden, wenn (a) Sie sind bereit, das komplette Image in den Speicher, und (den b) die Eingangstransformationen zu lesen, die Sie tun wollen, werden auf den folgenden Satz beschränkt:

    PNG_TRANSFORM_IDENTITY      No transformation
    PNG_TRANSFORM_STRIP_16      Strip 16-bit samples to
                                8 bits
    PNG_TRANSFORM_STRIP_ALPHA   Discard the alpha channel
    PNG_TRANSFORM_PACKING       Expand 1, 2 and 4-bit
                                samples to bytes
    PNG_TRANSFORM_PACKSWAP      Change order of packed
                                pixels to LSB first
    PNG_TRANSFORM_EXPAND        Perform set_expand()
    PNG_TRANSFORM_INVERT_MONO   Invert monochrome images
    PNG_TRANSFORM_SHIFT         Normalize pixels to the
                                sBIT depth
    PNG_TRANSFORM_BGR           Flip RGB to BGR, RGBA
                                to BGRA
    PNG_TRANSFORM_SWAP_ALPHA    Flip RGBA to ARGB or GA
                                to AG
    PNG_TRANSFORM_INVERT_ALPHA  Change alpha from opacity
                                to transparency
    PNG_TRANSFORM_SWAP_ENDIAN   Byte-swap 16-bit samples

(Das schließt das Setzen einer Hintergrundfarbe, Tun der Gammatransformation, Dithering, und Setzen des Füllers aus.), Wenn das einfach der Fall ist, tun Sie das:

 
    png_read_png(png_ptr, info_ptr, png_transforms, NULL)

wo png_transforms eine ganze Zahl ist, die das logische ODER von einem Satz von Transformationsfahnen enthält. Dieser Anruf ist zu png_read_info gleichwertig (), folgte dem Satz von Transformationen, die durch die umgestalten Maske, dann png_read_image (), und schließlich png_read_end () angezeigt sind.

(Der Endparameter dieses Anrufs wird noch nicht verwendet. Eines Tages könnte es zu durch einen zukünftigen Eingang erforderlichen Transformationsparametern hinweisen verwandeln sich.)

Nachdem Sie png_read_png genannt haben (), können Sie die Bilddaten damit abrufen

     row_pointers = png_get_rows(png_ptr, info_ptr);

wo row_pointers eine Reihe von Adressenverweisen zu den Pixel-Daten für jede Reihe ist:

   png_bytep row_pointers[height];

Wenn Sie Ihre Bildgröße und Pixel-Größe vorzeitig wissen, können Sie row_pointers vor dem Benennen png_read_png () damit allozieren

      row_pointers = png_malloc(png_ptr,
      height*sizeof(png_bytep));
   for (int i=0; i<height, i++)
      row_pointers[i]=png_malloc(png_ptr,
         width*pixel_size);
   png_set_rows(png_ptr, info_ptr, &row_pointers);

Wechselweise konnten Sie Ihr Image in einem großem Block allozieren und row_pointers [ich] definieren, um in die richtigen Plätze in Ihrem Block hinzuweisen.

Wenn Sie png_set_rows verwenden (), ist die Anwendung dafür verantwortlich, row_pointers zu befreien (und row_pointers [ich], wenn sie getrennt alloziert wurden).

Wenn Sie row_pointers vorzeitig nicht allozieren, png_read_png () wird es tun, und es wird free'ed sein, wenn Sie png_destroy_ * () nennen.

Die auf niedriger Stufe gelesene Schnittstelle

Wenn Sie die auf niedriger Stufe Route gehen, sind Sie jetzt bereit, die ganze Dateiinformation bis zu den wirklichen Bilddaten zu lesen. Sie tun das mit einem Anruf png_read_info ().

   png_read_info(png_ptr, info_ptr);

Das wird alle Klötze bis zu, aber nicht einschließlich der Bilddaten bearbeiten.

Das Abfragen der Info-Struktur

Funktionen werden verwendet, um die Information vom info_ptr zu bekommen, sobald es gelesen worden ist. Bemerken Sie, dass diese Felder nicht völlig ausgefüllt werden dürfen, bis png_read_end () hat die Klotz-Daten im Anschluss an das Image gelesen.

  png_get_IHDR(png_ptr, info_ptr, &width, &height,
       &bit_depth, &color_type, &interlace_type,
       &compression_type, &filter_method);

    width          - holds the width of the image
                     in pixels (up to 2^31).
    height         - holds the height of the image
                     in pixels (up to 2^31).
    bit_depth      - holds the bit depth of one of the
                     image channels.  (valid values are
                     1, 2, 4, 8, 16 and depend also on
                     the color_type.  See also
                     significant bits (sBIT) below).
    color_type     - describes which color/alpha channels
                         are present.
                     PNG_COLOR_TYPE_GRAY
                        (bit depths 1, 2, 4, 8, 16)
                     PNG_COLOR_TYPE_GRAY_ALPHA
                        (bit depths 8, 16)
                     PNG_COLOR_TYPE_PALETTE
                        (bit depths 1, 2, 4, 8)
                     PNG_COLOR_TYPE_RGB
                        (bit_depths 8, 16)
                     PNG_COLOR_TYPE_RGB_ALPHA
                        (bit_depths 8, 16)

                     PNG_COLOR_MASK_PALETTE
                     PNG_COLOR_MASK_COLOR
                     PNG_COLOR_MASK_ALPHA

    filter_method  - (must be PNG_FILTER_TYPE_BASE
                     for PNG 1.0, and can also be
                     PNG_INTRAPIXEL_DIFFERENCING if
                     the PNG datastream is embedded in
                     a MNG-1.0 datastream)
    compression_type - (must be PNG_COMPRESSION_TYPE_BASE
                     for PNG 1.0)
    interlace_type - (PNG_INTERLACE_NONE or
                     PNG_INTERLACE_ADAM7)
    Any or all of interlace_type, compression_type, of
    filter_method can be NULL if you are
    not interested in their values.

    channels = png_get_channels(png_ptr, info_ptr);
    channels       - number of channels of info for the
                     color type (valid values are 1 (GRAY,
                     PALETTE), 2 (GRAY_ALPHA), 3 (RGB),
                     4 (RGB_ALPHA or RGB + filler byte))
    rowbytes = png_get_rowbytes(png_ptr, info_ptr);
    rowbytes       - number of bytes needed to hold a row

    signature = png_get_signature(png_ptr, info_ptr);
    signature      - holds the signature read from the
                     file (if any).  The data is kept in
                     the same offset it would be if the
                     whole signature were read (i.e. if an
                     application had already read in 4
                     bytes of signature before starting
                     libpng, the remaining 4 bytes would
                     be in signature[4] through signature[7]
                     (see png_set_sig_bytes())).


    width            = png_get_image_width(png_ptr,
                         info_ptr);
    height           = png_get_image_height(png_ptr,
                         info_ptr);
    bit_depth        = png_get_bit_depth(png_ptr,
                         info_ptr);
    color_type       = png_get_color_type(png_ptr,
                         info_ptr);
    filter_method    = png_get_filter_type(png_ptr,
                         info_ptr);
    compression_type = png_get_compression_type(png_ptr,
                         info_ptr);
    interlace_type   = png_get_interlace_type(png_ptr,
                         info_ptr);

Diese sind auch wichtig, aber ihre Gültigkeit hängt ab, ob der Klotz gelesen worden ist. Der png_get_valid (png_ptr, info_ptr, PNG_INFO _ <Klotz>) und png_get _ <Klotz> (png_ptr, info_ptr...) geben Funktionen Nichtnull zurück, wenn die Daten, oder Null gelesen worden sind, wenn es vermisst wird. Die Parameter zum png_get _ <Klotz> werden direkt aufgestellt, wenn sie einfache Datentypen sind, oder ein Adressenverweis in den info_ptr für irgendwelche komplizierten Typen zurückgegeben wird.

 png_get_PLTE(png_ptr, info_ptr, &palette,
                     &num_palette);
    palette        - the palette for the file
                     (array of png_color)
    num_palette    - number of entries in the palette

    png_get_gAMA(png_ptr, info_ptr, &gamma);
    gamma          - the gamma the file is written
                     at (PNG_INFO_gAMA)

    png_get_sRGB(png_ptr, info_ptr, &srgb_intent);
    srgb_intent    - the rendering intent (PNG_INFO_sRGB)
                     The presence of the sRGB chunk
                     means that the pixel data is in the
                     sRGB color space.  This chunk also
                     implies specific values of gAMA and
                     cHRM.

    png_get_iCCP(png_ptr, info_ptr, &name,
       &compression_type, &profile, &proflen);
    name            - The profile name.
    compression     - The compression type; always
                      PNG_COMPRESSION_TYPE_BASE for PNG 1.0.
                      You may give NULL to this argument to
                      ignore it.
    profile         - International Color Consortium color
                      profile data. May contain NULs.
    proflen         - length of profile data in bytes.

    png_get_sBIT(png_ptr, info_ptr, &sig_bit);
    sig_bit        - the number of significant bits for
                     (PNG_INFO_sBIT) each of the gray,
                     red, green, and blue channels,
                     whichever are appropriate for the
                     given color type (png_color_16)

    png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans,
                     &trans_values);
    trans          - array of transparent entries for
                     palette (PNG_INFO_tRNS)
    trans_values   - graylevel or color sample values of
                     the single transparent color for
                     non-paletted images (PNG_INFO_tRNS)
    num_trans      - number of transparent entries
                     (PNG_INFO_tRNS)

    png_get_hIST(png_ptr, info_ptr, &hist);
                     (PNG_INFO_hIST)
    hist           - histogram of palette (array of
                     png_uint_16)

    png_get_tIME(png_ptr, info_ptr, &mod_time);
    mod_time       - time image was last modified
                    (PNG_VALID_tIME)

    png_get_bKGD(png_ptr, info_ptr, &background);
    background     - background color (PNG_VALID_bKGD)
                     valid 16-bit red, green and blue
                     values, regardless of color_type

    num_comments   = png_get_text(png_ptr, info_ptr,
                     &text_ptr, &num_text);
    num_comments   - number of comments
    text_ptr       - array of png_text holding image
                     comments
    text_ptr[i].compression - type of compression used
                 on "text" PNG_TEXT_COMPRESSION_NONE
                           PNG_TEXT_COMPRESSION_zTXt
                           PNG_ITXT_COMPRESSION_NONE
                           PNG_ITXT_COMPRESSION_zTXt
    text_ptr[i].key   - keyword for comment.  Must contain
                         1-79 characters.
    text_ptr[i].text  - text comments for current
                         keyword.  Can be empty.
    text_ptr[i].text_length - length of text string,
                 after decompression, 0 for iTXt
    text_ptr[i].itxt_length - length of itxt string,
                 after decompression, 0 for tEXt/zTXt
    text_ptr[i].lang  - language of comment (empty
                         string for unknown).
    text_ptr[i].lang_key  - keyword in UTF-8
                         (empty string for unknown).
    num_text       - number of comments (same as
                     num_comments; you can put NULL here
                     to avoid the duplication)
    Note while png_set_text() will accept text, language,
    and translated keywords that can be NULL pointers, the
    structure returned by png_get_text will always contain
    regular zero-terminated C strings.  They might be
    empty strings but they will never be NULL pointers.

    num_spalettes = png_get_sPLT(png_ptr, info_ptr,
       &palette_ptr);
    palette_ptr    - array of palette structures holding
                     contents of one or more sPLT chunks
                     read.
    num_spalettes  - number of sPLT chunks read.

    png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y,
       &unit_type);
    offset_x       - positive offset from the left edge
                     of the screen
    offset_y       - positive offset from the top edge
                     of the screen
    unit_type      - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER

    png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y,
       &unit_type);
    res_x          - pixels/unit physical resolution in
                     x direction
    res_y          - pixels/unit physical resolution in
                     x direction
    unit_type      - PNG_RESOLUTION_UNKNOWN,
                     PNG_RESOLUTION_METER

    png_get_sCAL(png_ptr, info_ptr, &unit, &width,
       &height)
    unit        - physical scale units (an integer)
    width       - width of a pixel in physical scale units
    height      - height of a pixel in physical scale units
                 (width and height are doubles)

    png_get_sCAL_s(png_ptr, info_ptr, &unit, &width,
       &height)
    unit        - physical scale units (an integer)
    width       - width of a pixel in physical scale units
    height      - height of a pixel in physical scale units
                 (width and height are strings like "2.54")

    num_unknown_chunks = png_get_unknown_chunks(png_ptr,
       info_ptr, &unknowns)
    unknowns          - array of png_unknown_chunk
                        structures holding unknown chunks
    unknowns[i].name  - name of unknown chunk
    unknowns[i].data  - data of unknown chunk
    unknowns[i].size  - size of unknown chunk's data
    unknowns[i].location - position of chunk in file

    The value of "i" corresponds to the order in which the
    chunks were read from the PNG file or inserted with the
    png_set_unknown_chunks() function.

Die Daten vom pHYs Klotz können in mehreren günstigen Formen abgerufen werden:

    res_x = png_get_x_pixels_per_meter(png_ptr,
       info_ptr)
    res_y = png_get_y_pixels_per_meter(png_ptr,
       info_ptr)
    res_x_and_y = png_get_pixels_per_meter(png_ptr,
       info_ptr)
    res_x = png_get_x_pixels_per_inch(png_ptr,
       info_ptr)
    res_y = png_get_y_pixels_per_inch(png_ptr,
       info_ptr)
    res_x_and_y = png_get_pixels_per_inch(png_ptr,
       info_ptr)
    aspect_ratio = png_get_pixel_aspect_ratio(png_ptr,
       info_ptr)

   (Each of these returns 0 [signifying "unknown"] if
       the data is not present or if res_x is 0;
       res_x_and_y is 0 if res_x != res_y)

Die Daten vom oFFs Klotz können in mehreren günstigen Formen abgerufen werden:

   x_offset = png_get_x_offset_microns(png_ptr, info_ptr);
    y_offset = png_get_y_offset_microns(png_ptr, info_ptr);
    x_offset = png_get_x_offset_inches(png_ptr, info_ptr);
    y_offset = png_get_y_offset_inches(png_ptr, info_ptr);

   (Each of these returns 0 [signifying "unknown" if both
       x and y are 0] if the data is not present or if the
       chunk is present but the unit is the pixel)

Für mehr Information, sieh die png_info Definition in png.h und der PNG Spezifizierung für den Klotz-Inhalt. Seien Sie mit dem Vertrauen rowbytes sorgfältig, weil einige der Transformationen zunehmen konnten, musste der Raum halten eine Reihe (dekomprimieren Sie Füller, gray_to_rgb, usw.). Sieh png_read_update_info () unten.

Ein schnelles Wort über text_ptr und num_text. PNG speichert Anmerkungen in Paaren des Schlüsselwortes/Textes, einem Paar pro Klotz, ohne Grenze auf der Anzahl von Textklötzen, und eine 2^31-Byte-Grenze auf ihrer Größe. Während dort Schlüsselwörter angedeutet werden, gibt es keine Voraussetzung, um den Gebrauch auf diese Schnuren einzuschränken. Es wird stark darauf hingewiesen, dass Schlüsselwörter und Text Menschen (das ist die Frage!) vernünftig sind, verwenden Sie Abkürzungen so nicht. Nicht bedruckbaren Symbolen wird nicht erlaubt. Sieh die PNG Spezifizierung für mehr Details. Es gibt auch keine Voraussetzung, um Text nach dem Schlüsselwort zu haben.

Schlüsselwörter sollten auf 79 lateinische 1 Zeichen beschränkt werden ohne zu führen oder nachfolgende Leerzeichen, aber Nichtkonsekutivräumen wird innerhalb des Schlüsselwortes erlaubt. Es ist möglich, dasselbe Schlüsselwort jede Anzahl von Zeiten zu haben. Der text_ptr ist eine Reihe von png_text Strukturen, jeder, einen Adressenverweis zu einer Sprachschnur, einen Adressenverweis zu einem Schlüsselwort und einen Adressenverweis zu einer Textfolge haltend. Die Textfolge, der Sprachcode, und das übersetzte Schlüsselwort können leere oder UNGÜLTIGE Adressenverweise sein. Die Paare des Schlüsselwortes/Textes werden in die Reihe in der Ordnung gebracht, dass sie erhalten werden. Jedoch können einige oder alle Textklötze sein nach dem Image, um so sich zu überzeugen, haben Sie alle Textklötze gelesen, panschen Sie mit diesen nicht, bis Sie das Zeug nach dem Image lesen. Das wird wieder unten in der Diskussion erwähnt, die mit png_read_end () geht.

Eingangstransformationen

Nachdem Sie die Kopfball-Information gelesen haben, können Sie die Bibliothek aufstellen, um irgendwelche speziellen Transformationen der Bilddaten zu behandeln. Die verschiedenen Wege, die Daten umzugestalten, werden in der Ordnung beschrieben, dass sie vorkommen sollten. Das ist wichtig, weil einige von diesen den Farbentyp and/or Bit-Tiefe der Daten ändern, und einige andere nur an bestimmten Farbentypen und Bit-Tiefen arbeiten. Wenn auch jede Transformation überprüft, um zu sehen, ob sie Daten hat, mit denen sie etwas tun kann, sollten Sie sich überzeugen, um nur eine Transformation zu ermöglichen, wenn es für die Daten gültig sein wird. Tauschen Sie zum Beispiel rot und blau auf grayscale Daten nicht.

Die Farben, die für den Hintergrund und die Durchsichtigkeitswerte verwendet sind, sollten in demselben Format/Tiefe wie die gegenwärtigen Bilddaten geliefert werden. Sie werden in demselben Format/Tiefe wie die Bilddaten in einem bKGD oder tRNS Klotz gespeichert, so ist das, welcher libpng dafür Daten erwartet. Die Farben werden umgestaltet, um synchron mit den Bilddaten zu bleiben, wenn eine Anwendung den png_read_update_info () Routine (sieh unten) nennt.

Daten werden in die gelieferten in Bytes gepackten Reihe-Puffer decodiert es sei denn, dass die Bibliothek gesagt worden ist, es in ein anderes Format umzugestalten. Zum Beispiel werden 4 Bit/Pixel paletted oder grayscale Daten 2 Pixel/Byte mit dem leftmost Pixel in den höherwertigen Bit des Bytes zurückgegeben, es sei denn, dass png_set_packing () genannt wird. RGB 8-Bit-Daten werden in RGB RGB RGB Format gespeichert es sei denn, dass png_set_filler () genannt wird, um Füllzeichen entweder vorher oder nach jedem RGB Drilling einzufügen. RGB 16-Bit-Daten werden RRGGBB RRGGBB mit dem bedeutendsten Byte des Farbwerts zuerst zurückgegeben, es sei denn, dass png_set_strip_16 () genannt wird, um es in regelmäßigen RGB RGB Drillinge umzugestalten, oder png_set_filler () genannt wird, um Füllzeichen entweder vorher oder nach jedem RRGGBB Drilling einzufügen. Ähnlich können 8 Bit oder 16 Bit grayscale Daten mit png_set_filler () oder png_set_strip_16 () modifiziert werden.

Der folgende Code gestaltet grayscale Images von weniger als 8 bis 8 Bit um, ändert paletted Images zu RGB, und fügt einen vollen Alfakanal hinzu, wenn es Durchsichtigkeitsinformation in einem tRNS Klotz gibt. Das ist auf grayscale Images mit Bit-Tiefen 2 oder 4 am nützlichsten, oder wenn es eine Vielfach-Bildbetrachtungsanwendung gibt, die alle Images ebenso behandeln möchte.

   if (color_type == PNG_COLOR_TYPE_PALETTE)
        png_set_palette_to_rgb(png_ptr);

    if (color_type == PNG_COLOR_TYPE_GRAY &&
        bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr);

    if (png_get_valid(png_ptr, info_ptr,
        PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);

Diese drei Funktionen sind wirklich Decknamen für png_set_expand (), hinzugefügt in der libpng Version 1.0.4 mit den Funktionsnamen, die dekomprimiert sind, um Codelesbarkeit zu verbessern. In einer zukünftigen Version können sie wirklich verschiedene Sachen machen.

PNG kann Dateien mit 16 Bit pro Kanal haben. Wenn Sie nur 8 Bit pro Kanal behandeln können, wird das die Pixel unten zu 8 Bit abziehen.

if (bit_depth == 16)
        png_set_strip_16(png_ptr);

Wenn, aus irgendeinem Grund, Sie den Alfakanal auf einem Image nicht brauchen, und Sie ihn entfernen wollen, anstatt ihn mit dem Hintergrund zu verbinden (aber der Bildautor hatte sicher das Sie im Sinn, verbinden *would* ihn mit dem Hintergrund, so ist es, was Sie wahrscheinlich tun sollten):

     if (color_type & PNG_COLOR_MASK_ALPHA)
        png_set_strip_alpha(png_ptr);
 

In PNG Dateien ist der Alfakanal in einem Image das Niveau der Undurchsichtigkeit. Wenn Sie den Alfakanal in einem Image brauchen, um das Niveau der Durchsichtigkeit statt der Undurchsichtigkeit zu sein, können Sie den Alfakanal umkehren (oder die tRNS Klotz-Daten), nachdem es gelesen wird, so dass 0 völlig undurchsichtig ist und 255 (in 8 Bit oder paletted Images) oder 65535 (in 16 Bitbildern), damit völlig durchsichtig ist

    png_set_invert_alpha(png_ptr);

PNG Dateien packen Pixel von Bit-Tiefen 1, 2, und 4 in ebenso kleine Bytes ein, wie sie können, zum Beispiel, 8 Pixel pro Byte für 1-Bit-Dateien hinauslaufend. Dieser Code dekomprimiert zu 1 Pixel pro Byte, ohne die Werte der Pixel zu ändern:

    if (bit_depth < 8)
        png_set_packing(png_ptr);

PNG Dateien haben mögliche Bit-Tiefen 1, 2, 4, 8, und 16. Alle in einem PNG Image gespeicherten Pixel sind "erklettert" oder bis zum folgenden höher mögliche Bit-Tiefe (z.B von 5 Bit/Probe in der Reihe [0,31] zu 8 Bit/Probe in der Reihe [0, 255]) "ausgewechselt" "worden". Jedoch ist es auch möglich, die PNG Pixel-Daten zurück zur ursprünglichen Bit-Tiefe des Images umzuwandeln. Dieser Anruf nimmt ab die Pixel treten zur ursprünglichen Bit-Tiefe zurück:

     png_color_8p sig_bit;

    if (png_get_sBIT(png_ptr, info_ptr, &sig_bit))
        png_set_shift(png_ptr, sig_bit);

PNG Dateien speichern 3-farbige Pixel in der roten, grünen, blauen Ordnung. Dieser Code ändert die Speicherung der Pixel zu blau, grün, rot:

    if (color_type == PNG_COLOR_TYPE_RGB ||
        color_type == PNG_COLOR_TYPE_RGB_ALPHA)
        png_set_bgr(png_ptr);

PNG Dateien speichern RGB in 3 oder 6 Bytes gepackte Pixel. Dieser Code dekomprimiert sie in 4 oder 8 Bytes für Fenstertechnik-Systeme, die sie in diesem Format brauchen:

    if (color_type == PNG_COLOR_TYPE_RGB)
        png_set_filler(png_ptr, filler, PNG_FILLER_BEFORE);

wo "Füller" die 8 oder 16 Bit-Anzahl ist, um sich mit zu füllen, und die Speicherstelle entweder PNG_FILLER_BEFORE oder PNG_FILLER_AFTER, abhängig davon ist, ob Sie den Füller vor dem RGB oder danach wollen. Diese Transformation betrifft Images nicht, die bereits volle Alfakanäle haben. Um einen undurchsichtigen Alfakanal hinzuzufügen, verwenden Sie filler=0xff oder 0xffff und PNG_FILLER_AFTER, der RGBA Pixel erzeugen wird.

Wenn Sie ein Image mit einem Alfakanal lesen, und Sie die Daten brauchen, weil ARGB statt des normalen PNG RGBA formatieren:

    if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
        png_set_swap_alpha(png_ptr);

Für etwas Gebrauch können Sie wollen, dass ein grayscale Image als RGB vertreten wird. Dieser Code wird diese Konvertierung tun:

    if (color_type == PNG_COLOR_TYPE_GRAY ||
        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
          png_set_gray_to_rgb(png_ptr);

Umgekehrt können Sie einen RGB oder RGBA Image zu grayscale oder grayscale mit dem Alpha umwandeln.

    if (color_type == PNG_COLOR_TYPE_RGB ||
        color_type == PNG_COLOR_TYPE_RGB_ALPHA)
          png_set_rgb_to_gray_fixed(png_ptr, error_action,
             int red_weight, int green_weight);

    error_action = 1: silently do the conversion
    error_action = 2: issue a warning if the original
                      image has any pixel where
                      red != green or red != blue
    error_action = 3: issue an error and abort the
                      conversion if the original
                      image has any pixel where
                      red != green or red != blue

    red_weight:       weight of red component times 100000
    green_weight:     weight of green component times 100000
                      If either weight is negative, default
                      weights (21268, 71514) are used.

Wenn Sie error_action = 1 oder 2 gesetzt haben, können Sie später überprüfen, ob das Image wirklich, nach der Verarbeitung der Bildreihen, mit dem png_get_rgb_to_gray_status (png_ptr) Funktion grau war. Es wird einen png_byte zurückgeben, der Null ist, wenn das Image grau war oder 1, wenn es irgendwelche nichtgrauen Pixel gab. bKGD und sBIT Daten werden zu grayscale still umgewandelt, die grünen Kanaldaten unabhängig von der error_Action-Einstellung verwendend.

Mit red_weight+green_weight <=100000 wird der normalisierte graylevel geschätzt:

    int rw = red_weight * 65536;
    int gw = green_weight * 65536;
    int bw = 65536 - (rw + gw);
    gray = (rw*red + gw*green + bw*blue)/65536;

Die Ausgangsparameter kommen denjenigen näher, die in den häufig gestellten Farbenfragen von Charles Poynton, <http://www.inforamp.net / ~ poynton/> Copyright (c) 1998-01-04 Charles Poynton poynton@inforamp.net empfohlen sind

    Y = 0.212671 * R + 0.715160 * G + 0.072169 * B

Libpng kommt dem damit näher

    Y = 0.21268 * R + 0.7151 * G + 0.07217 * B 

der mit ganzen Zahlen als ausgedrückt werden kann

    Y = (6969 * R + 23434 * G + 2365 * B)/32768 

Die Berechnung wird in einem geradlinigen colorspace getan, wenn das Bildgamma bekannt ist.

Wenn Sie einen grayscale haben und Sie png_set_expand_depth (), png_set_expand (), oder png_set_gray_to_rgb verwenden, um sich zu truecolor oder zu einer höheren Bit-Tiefe zu ändern, müssen Sie entweder die Hintergrundfarbe als ein grauer Wert an der ursprünglichen Dateibit-Tiefe (need_expand = 1) oder Versorgung die Hintergrundfarbe als ein RGB Drilling an der endgültigen, dekomprimierten Bit-Tiefe (need_expand = 0) liefern. Ähnlich, wenn Sie ein paletted Image lesen, müssen Sie entweder die Hintergrundfarbe als ein Palette-Index (need_expand = 1) oder als ein RGB Drilling liefern, der kann oder in der Palette (need_expand = 0) nicht sein kann.

 png_color_16 my_background;
    png_color_16p image_background;

    if (png_get_bKGD(png_ptr, info_ptr, &image_background))
        png_set_background(png_ptr, image_background,
          PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
    else
        png_set_background(png_ptr, &my_background,
          PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);

Der png_set_background () Funktion erzählt libpng zu zerlegbaren Images mit dem Alpha oder der einfachen Durchsichtigkeit gegen die gelieferte Hintergrundfarbe. Wenn die PNG Datei einen bKGD Klotz enthält (gültiger PNG_INFO_bKGD), können Sie diese Farbe verwenden, oder eine andere für die gegenwärtige Anzeige passendere Farbe (z.B, die Hintergrundfarbe von einer Webseite) liefern. Sie müssen libpng erzählen, ob die Farbe im Gammaraum der Anzeige ist (PNG_BACKGROUND_GAMMA_SCREEN für Farben, die Sie liefern), die Datei (PNG_BACKGROUND_GAMMA_FILE für Farben vom bKGD Klotz), oder derjenige, der kein dieser Gammas ist (PNG_BACKGROUND_GAMMA_UNIQUE - weiß ich nicht, warum irgendjemand das verwenden würde, aber es ist hier).

Um PNG Images auf jeder Art des Systems richtig anzuzeigen, muss die Anwendung wissen, wie das Anzeige-Gamma ist. Ideal wird der Benutzer das wissen, und die Anwendung wird ihnen erlauben, es zu setzen. Eine Methode, dem Benutzer zu erlauben, das Anzeige-Gamma getrennt für jedes System zu setzen, soll für einen SCREEN_GAMMA oder DISPLAY_GAMMA Umgebungsvariable überprüfen, die hoffentlich richtig gesetzt wird.

Bemerken Sie, dass display_gamma die gesamte Gammakorrektur ist, die erforderlich ist, angenehme Ergebnisse zu produzieren, der von den Lichtverhältnissen in der Umgebungsumgebung abhängt. In einem dunklen oder hell angezündeten Zimmer ist keine Entschädigung außer der physischen Gammahochzahl des Monitors erforderlich, während in einem dunklen Zimmer eine ein bisschen kleinere Hochzahl besser ist.

  double gamma, screen_gamma;

   if (/* We have a user-defined screen
       gamma value */)
   {
      screen_gamma = user_defined_screen_gamma;
   }
   /* One way that applications can share the same
      screen gamma value */
   else if ((gamma_str = getenv("SCREEN_GAMMA"))
      != NULL)
   {
      screen_gamma = (double)atof(gamma_str);
   }
   /* If we don't have another value */
   else
   {
      screen_gamma = 2.2; /* A good guess for a
           PC monitor in a bright office or a dim room */
      screen_gamma = 2.0; /* A good guess for a
           PC monitor in a dark room */
      screen_gamma = 1.7 or 1.0;  /* A good
           guess for Mac systems */
   }

Die png_set_gamma () fungieren Griff-Gammatransformationen der Daten. Passieren Sie sowohl das Dateigamma als auch den Strom screen_gamma. Wenn die Datei einen Gammawert nicht hat, können Sie denjenigen irgendwie passieren, wenn Sie eine Idee haben, was es ist (gewöhnlich 0.45455, ist eine gute Annahme für GIF-Images auf PCs). Bemerken Sie, dass Dateigammas von Bildschirm-Gammas umgekehrt werden. Sieh die Diskussionen über das Gamma in der PNG Spezifizierung für eine ausgezeichnete Beschreibung dessen, welches Gamma ist, und warum alle Anwendungen es unterstützen sollten. Es wird dass PNG Zuschauer-Support-Gammakorrektur stark empfohlen.

 if (png_get_gAMA(png_ptr, info_ptr, &gamma))
      png_set_gamma(png_ptr, screen_gamma, gamma);
   else
      png_set_gamma(png_ptr, screen_gamma, 0.45455);

Wenn Sie eine RGB Datei auf eine paletted Datei reduzieren müssen, oder wenn eine paletted Datei mehr Einträge hat, dann wird auf Ihrem Bildschirm passen, png_set_dither () wird das tun. Bemerken Sie, dass das eine einfache Übereinstimmungsaufregung ist, die bloß die nächste Farbe verfügbar findet. Das sollte ziemlich gut mit optimierten Paletten, und ziemlich schlecht mit geradlinigen Farbenwürfeln arbeiten. Wenn Sie eine Palette passieren, die dann maximum_colors größer ist, wird die Datei die Anzahl von Farben in der Palette vermindern, so wird es maximum_colors einbauen. Wenn es einen histogram gibt, wird es es verwenden, um intelligentere Wahlen zu machen, die Palette reduzierend. Wenn es keinen histogram gibt, kann es nicht als gut ein Job tun.

  if (color_type & PNG_COLOR_MASK_COLOR)
   {
      if (png_get_valid(png_ptr, info_ptr,
         PNG_INFO_PLTE))
      {
         png_uint_16p histogram = NULL;

         png_get_hIST(png_ptr, info_ptr,
            &histogram);
         png_set_dither(png_ptr, palette, num_palette,
            max_screen_colors, histogram, 1);
      }
      else
      {
         png_color std_color_cube[MAX_SCREEN_COLORS] =
            { ... colors ... };

         png_set_dither(png_ptr, std_color_cube,
            MAX_SCREEN_COLORS, MAX_SCREEN_COLORS,
            NULL,0);
      }
   }

PNG Dateien beschreiben monochrom als schwarz, Null und weiß seiend, ein seiend. Der folgende Code wird das umkehren (machen Sie schwarz, ein und weiß zu sein, Null sein):

   if (bit_depth == 1 && color_type == PNG_COLOR_TYPE_GRAY)
      png_set_invert_mono(png_ptr);

Diese Funktion kann auch verwendet werden, um grayscale und Images des grauen Alphas umzukehren:

   if (color_type == PNG_COLOR_TYPE_GRAY ||
        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
      png_set_invert_mono(png_ptr);

PNG Dateien speichern 16-Bit-Pixel in der Netzwerksbyte-Ordnung (groß-endian, d. h.. die meisten bedeutenden Bit zuerst). Dieser Code ändert die Speicherung zum anderen Weg (wenig-endian, d. h. am wenigsten bedeutende Bit zuerst, der Weg, wie PCs sie speichern):

     if (bit_depth == 16)
        png_set_swap(png_ptr);

Wenn Sie einpacken-Bildpunktabbilder (1, 2, oder 4 Bit/Pixel) verwenden, und Sie die Ordnung ändern müssen, sind die Pixel in Bytes gepackt, Sie können verwenden:

   if (bit_depth < 8)
       png_set_packswap(png_ptr);

Schließlich können Sie Ihre eigene Transformationsfunktion schreiben, wenn keiner der vorhandenen Ihren Bedarf deckt. Das wird getan, eine Rückrufaktion damit setzend

  png_set_read_user_transform_fn(png_ptr,
       read_transform_fn);

Sie müssen die Funktion liefern

    void read_transform_fn(png_ptr ptr, row_info_ptr
       row_info, png_bytep data)

Sieh pngtest.c für ein Arbeitsbeispiel. Ihre Funktion wird genannt, nachdem alle anderen Transformationen bearbeitet worden sind.

Sie können auch einen Adressenverweis zu einer Benutzerstruktur für den Gebrauch durch Ihre Rückrufaktionsfunktion aufstellen, und Sie können libpng informieren, der Ihr, umgestaltest Funktion, die Anzahl von Kanälen ändern wird oder Tiefe mit der Funktion beißt

    png_set_user_transform_info(png_ptr, user_ptr,
       user_depth, user_channels);

Die Anwendung des Benutzers, nicht libpng, ist dafür verantwortlich, jeden für die Benutzerstruktur erforderlichen Speicher zu allozieren und zu befreien.

Sie können den Adressenverweis über die Funktion png_get_user_transform_ptr () abrufen. Zum Beispiel:

      voidp read_user_transform_ptr =
       png_get_user_transform_ptr(png_ptr);

Das letzte Ding zu behandeln verflicht sich; das wird im Detail unten bedeckt, aber Sie müssen die Funktion hier nennen, wenn Sie wollen, dass libpng Vergrößerung des verflochtenen Images behandelt.

     number_of_passes = png_set_interlace_handling(png_ptr);

Nach dem Setzen der Transformationen kann libpng Ihre png_info Struktur aktualisieren, um irgendwelche Transformationen zu widerspiegeln, um die Sie mit diesem Anruf gebeten haben. Das ist am nützlichsten, um das rowbytes Feld der Struktur des Infos zu aktualisieren, so können Sie es verwenden, um Ihren Bildspeicher zu allozieren. Diese Funktion wird auch Ihre Palette mit dem richtigen screen_gamma und Hintergrund aktualisieren, wenn diesen mit den Anrufen oben gegeben worden ist.

   png_read_update_info(png_ptr, info_ptr);

Nachdem Sie png_read_update_info nennen (), können Sie jeden Speicher allozieren Sie müssen das Image halten. Die Reihe-Daten sind einfach rohe Byte-Daten für alle Formen von Images. Weil sich die wirkliche Allozierung unter Anwendungen ändert, wird kein Beispiel angeführt. Wenn Sie einen großen Klotz allozieren, werden Sie eine Reihe von Adressenverweisen zu jeder Reihe bauen müssen, weil es für einige der Funktionen unten erforderlich sein wird.

Das Lesen von Bilddaten

Nachdem Sie Speicher alloziert haben, können Sie die Bilddaten lesen. Der einfachste Weg zu tun ist das in einem Funktionsaufruf. Wenn Sie genug Speicher allozieren, um das ganze Image zu halten, können Sie gerade png_read_image nennen (), und libpng wird in allen Bilddaten lesen und es im gelieferten Speicherbereich stellen. Sie werden in einer Reihe von Adressenverweisen zu jeder Reihe gehen müssen.

Diese Funktion behandelt automatisch das Verflechten, so brauchen Sie nicht png_set_interlace_handling () zu nennen oder diese Funktion mehrmals, oder einige dieses anderen mit png_read_rows notwendigen Zeugs () zu nennen.

   png_read_image(png_ptr, row_pointers);

wo row_pointers ist:

    png_bytep row_pointers[height];

Sie können zur Leere oder Rotforelle hinweisen, oder was auch immer Sie für Pixel verwenden.

Wenn Sie im ganzen Image sofort nicht lesen wollen, können Sie png_read_rows () stattdessen verwenden. Wenn sich dort nicht verflechtend ist (überprüfen Sie interlace_type == PNG_INTERLACE_NONE), ist das einfach:

   png_read_rows(png_ptr, row_pointers, NULL,
       number_of_rows);

wo row_pointers dasselbe als im png_read_image () Anruf ist.

Wenn Sie das gerade eine Reihe auf einmal tun, können Sie das mit einem einzelnen row_pointer statt einer Reihe von row_pointers tun:

     png_bytep row_pointer = row;
    png_read_row(png_ptr, row_pointer, NULL);

Wenn die Datei verflochten wird (interlace_type! = 0 im IHDR Klotz), Dinge werden etwas härter. Der einzige Strom (PNG Spezifizierungsversion 1.2) der sich verflechtende Typ für PNG ist (interlace_type == PNG_INTERLACE_ADAM7) ist ein etwas kompliziertes 2. Zwischenzeile-Schema, bekannt als Adam7, der ein Image in sieben kleinere Images der unterschiedlichen Größe bricht, die auf 8x8 Bratrost basiert ist.

libpng kann jene Images ausfüllen, oder er kann sie Ihnen geben, "als ist". Wenn Sie sie ausgefüllt wollen, gibt es zwei Wege, das zu tun. In der PNG Spezifizierung erwähnter derjenige soll jedes Pixel dekomprimieren, um jene Pixel zu bedecken, die noch (die "Rechteck"-Methode) nicht gelesen worden sind. Das läuft auf ein blocky Image für den ersten Pass hinaus, der allmählich wegräumt, weil mehr Pixel gelesen werden. Die andere Methode ist die "sprühen" Methode, wo Pixel nur in ihren Endspeicherstellen mit dem Rest des Images gezogen werden, das beliebige Farben bleibt, wurden sie zu vor dem Anfang des gelesenen initialisiert. Die erste Methode sieht gewöhnlich besser aus, aber neigt dazu, langsamer zu sein, weil es mehr Pixel gibt, um in den Reihen zu stellen.

Wenn Sie nicht wollen, dass libpng die sich verflechtenden Details behandelt, nennen Sie gerade png_read_rows () siebenmal, um in allen sieben Images zu lesen. Jedes der Images ist ein gültiges Image allein, oder sie können alle auf 8x8 Bratrost verbunden werden, um ein einzelnes Image zu bilden (obwohl, wenn Sie vorhaben, sie zu verbinden, Sie vom Verwenden des Libpng-Zwischenzeile-Berührens viel besser sein würden).

Der erste Pass wird ein Image 1/8 ebenso breit zurückgeben wie das komplette Image (jede 8. Säule, die in der Säule 0 anfängt) und 1/8 ebenso hoch wie das Original (jede 8. Reihe, die in der Reihe 0 anfängt), das zweite wird 1/8 als breit sein (in der Säule 4 anfangend), und 1/8 als hoch (auch in der Reihe 0 anfangend). Der dritte Pass wird 1/4 als breit (jedes 4. Pixel sein, die, das in der Säule 0 anfängt) und 1/8 als hoch (jede 8. Reihe in der Reihe 4 anfängt), und der vierte Pass wird 1/4 ebenso breit und 1/4 sein wie hoch (jede 4. Säule, die, die in der Säule 2, und jede 4. Reihe anfängt in der Reihe 0 anfängt). Der fünfte Pass wird ein Image 1/2 ebenso breit, und 1/4 zurückgeben wie hoch (an der Säule 0 und Reihe 2 anfangend), während der sechste Pass 1/2 ebenso breit und 1/2 ebenso hoch sein wird wie das Original (in der Säule 1 und Reihe 0 anfangend). Der siebente und endgültige Pass wird als das Original, und der 1/2 ebenso breit sein, weil hoch, alle sonderbaren enthaltend, scanlines zählte. Puh!

Wenn Sie wollen, dass libpng die Images dekomprimiert, nennen Sie das vor dem Benennen png_start_read_image () oder png_read_update_info ():

      if (interlace_type == PNG_INTERLACE_ADAM7)
        number_of_passes
           = png_set_interlace_handling(png_ptr);

Das wird die Anzahl von erforderlichen Pässen zurückgeben. Zurzeit ist das sieben, aber kann sich ändern, wenn ein anderer Zwischenzeile-Typ hinzugefügt wird. Diese Funktion kann genannt werden, selbst wenn die Datei nicht verflochten wird, wohin es einen Pass zurückgeben wird.

Wenn Sie nicht dabei sind, das Image nach jedem Pass anzuzeigen, aber dabei sind zu warten, bis das komplette Image gelesen wird in, die sprühen Wirkung zu verwenden. Diese Wirkung ist schneller, und das Endergebnis jeder Methode ist genau dasselbe. Wenn Sie beim Anzeigen des Images planen, nachdem jeder Pass, die "Rechteck"-Wirkung allgemein als das bessere Aussehen ein betrachtet wird.

Wenn Sie nur die "sprühen" Wirkung wollen, nennen Sie gerade png_read_rows () als normal, mit dem dritten Parameter UNGÜLTIG. Stellen Sie sicher, dass Sie machen, übertragen das Image number_of_passes Zeiten, und Sie ändern die Daten in den Reihen zwischen Anrufen nicht. Sie können die Speicherstellen der Daten, gerade nicht die Daten ändern. Jeder Pass schreibt nur die Pixel, die für diesen Pass, und nimmt passend sind, an, dass die Daten von vorherigen Pässen noch gültig sind.

      png_read_rows(png_ptr, row_pointers, NULL,
       number_of_rows);

Wenn Sie nur die erste Wirkung (die Rechtecke) wollen, wie zuvor außer dem Pass der Reihe-Puffer im dritten Parameter dasselbe machen, und den zweiten Parameter UNGÜLTIG verlassen.

      png_read_rows(png_ptr, NULL, row_pointers,
       number_of_rows);

Das Vollenden eines gelesenen folgenden

Nachdem Sie beendet werden, das Image entweder durch das hohe - oder durch die auf niedriger Stufe Schnittstellen lesend, können Sie beenden, die Datei zu lesen. Wenn Sie sich für Anmerkungen oder Zeit interessieren, die entweder vorher oder nach den Bilddaten gespeichert werden kann, sollten Sie den getrennten png_info struct passieren, wenn Sie die Anmerkungen aus der Zeit vor und nach dem Image getrennt halten wollen. Wenn Sie sich nicht interessieren, können Sie UNGÜLTIG gehen.

  png_read_end(png_ptr, end_info);

Wenn Sie getan werden, können Sie den ganzen Speicher befreien, der durch libpng wie das alloziert ist:

    png_destroy_read_struct(&png_ptr, &info_ptr,
       &end_info);

Es ist auch dazu möglich einzeln befreien die info_ptr Mitglieder, die zur libpng-allozierten Speicherung mit der folgenden Funktion hinweisen:

     png_free_data(png_ptr, info_ptr, mask, seq)
    mask - identifies data to be freed, a mask
           containing the logical OR of one or
           more of
             PNG_FREE_PLTE, PNG_FREE_TRNS,
             PNG_FREE_HIST, PNG_FREE_ICCP,
             PNG_FREE_PCAL, PNG_FREE_ROWS,
             PNG_FREE_SCAL, PNG_FREE_SPLT,
             PNG_FREE_TEXT, PNG_FREE_UNKN,
           or simply PNG_FREE_ALL
    seq  - sequence number of item to be freed
           (-1 for all items)

Diese Funktion kann sicher genannt werden, als die relevante Speicherung bereits befreit worden ist, oder noch nicht alloziert worden ist, oder vom Benutzer und nicht durch libpng alloziert wurde, und in jenen Fällen wird nichts tun. Der "seq" Parameter wird ignoriert, wenn nur einem Artikel des ausgewählten Datentyps, wie PLTE, erlaubt wird. Wenn "seq" nicht-1 ist, und vielfachen Sachen für den Datentyp erlaubt wird, der in der Maske, wie Text oder sPLT identifiziert ist, wird nur der n'th Artikel in der Struktur befreit, wo n "seq" ist.

Das Verzug-Verhalten ist nur, Daten zu befreien, der innerlich durch libpng alloziert wurde. Das kann geändert werden, so dass libpng die Daten nicht befreien wird, oder so dass er Daten befreien wird, der vom Benutzer mit png_malloc () oder png_zalloc () alloziert wurde und in über einen png_set_ * () Funktion, damit ging

    png_data_freer(png_ptr, info_ptr, freer, mask)
    mask   - which data elements are affected
             same choices as in png_free_data()
    freer  - one of
               PNG_DESTROY_WILL_FREE_DATA
               PNG_SET_WILL_FREE_DATA
               PNG_USER_WILL_FREE_DATA

Diese Funktion betrifft nur Daten, der bereits alloziert worden ist. Sie können diese Funktion nach dem Lesen der PNG Daten, aber vor dem Benennen jedes png_set_ * () Funktionen nennen, um zu kontrollieren, ob der Benutzer oder der png_set_ * () Funktion dafür verantwortlich ist, irgendwelche vorhandenen Daten zu befreien, die, und wieder nach dem png_set_ * () Funktionen da sein könnten zu kontrollieren, ob der Benutzer oder png_destroy_ * () die Daten befreien sollen. Wenn der Benutzer Verantwortung für libpng-allozierte Daten annimmt, muss die Anwendung png_free () verwenden, um sie zu befreien, und wenn der Benutzer Verantwortung libpng für Daten überträgt, die der Benutzer alloziert hat, muss der Benutzer png_malloc () oder png_zalloc () verwendet haben, um sie zu allozieren.

Wenn Sie Ihren row_pointers in einem einzelnen Block, wie angedeutet, oben in der Beschreibung des hohen Niveaus gelesene Schnittstelle allozierten, müssen Sie nicht Verantwortung übertragen, um es zum png_set_rows oder der png_read_Destroy-Funktion zu befreien, weil sie auch versuchen würden, den einzelnen row_pointers [ich] zu befreien.

Wenn Sie text_ptr.text, text_ptr.lang, und text_ptr.translated_keyword getrennt allozierten, übertragen Sie Verantwortung nicht, um text_ptr zu libpng zu befreien, weil, wenn libpng eine png_text Struktur füllt, es diese Mitglieder mit dem Schlüsselmitglied verbindet, und png_free_data () nur text_ptr.key befreien wird. Ähnlich, wenn Sie Verantwortung für free'ing text_ptr von libpng bis Ihre Anwendung übertragen, muss Ihre Anwendung nicht jene Mitglieder getrennt befreien.

Der png_free_data () Funktion wird die "gültige" Fahne für irgendetwas abdrehen, was es befreit. Wenn Sie die Fahne für einen Klotz abdrehen müssen, der durch Ihre Anwendung statt durch libpng befreit wurde, können Sie verwenden

  png_set_invalid(png_ptr, info_ptr, mask);
    mask - identifies the chunks to be made invalid,
           containing the logical OR of one or
           more of
             PNG_INFO_gAMA, PNG_INFO_sBIT,
             PNG_INFO_cHRM, PNG_INFO_PLTE,
             PNG_INFO_tRNS, PNG_INFO_bKGD,
             PNG_INFO_hIST, PNG_INFO_pHYs,
             PNG_INFO_oFFs, PNG_INFO_tIME,
             PNG_INFO_pCAL, PNG_INFO_sRGB,
             PNG_INFO_iCCP, PNG_INFO_sPLT,
             PNG_INFO_sCAL, PNG_INFO_IDAT

Für ein kompakteres Beispiel, ein PNG Image zu lesen, sieh die Datei example.c.

Das Lesen von PNG Dateien progressiv

Der progressive Leser ist dann der nichtprogressive Leser ein bisschen verschieden. Anstatt png_read_info (), png_read_rows (), und png_read_end () zu nennen, machen Sie einen Anruf png_process_data (), welcher Rückrufaktionen nennt, wenn es das Info, eine Reihe, oder das Ende des Images hat. Sie stellen diese Rückrufaktionen mit png_set_progressive_read_fn () auf. Sie müssen sich nicht über die Funktionen des Eingangs/Produktion von libpng sorgen, weil Sie der Bibliothek die Daten direkt in png_process_data () geben. Ich werde annehmen, dass Sie die Abteilung beim Lesen von PNG Dateien oben gelesen haben, so werde ich nur die Unterschiede hervorheben (obwohl ich den ganzen Code zeigen werde).

png_structp png_ptr;
png_infop info_ptr;

 /*  An example code fragment of how you would
     initialize the progressive reader in your
     application. */
 int
 initialize_png_reader()
 {
    png_ptr = png_create_read_struct
        (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
         user_error_fn, user_warning_fn);
    if (!png_ptr)
        return (ERROR);
    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr)
    {
        png_destroy_read_struct(&png_ptr, (png_infopp)NULL,
           (png_infopp)NULL);
        return (ERROR);
    }

    if (setjmp(png_jmpbuf(png_ptr)))
    {
        png_destroy_read_struct(&png_ptr, &info_ptr,
           (png_infopp)NULL);
        return (ERROR);
    }

    /* This one's new.  You can provide functions
       to be called when the header info is valid,
       when each row is completed, and when the image
       is finished.  If you aren't using all functions,
       you can specify NULL parameters.  Even when all
       three functions are NULL, you need to call
       png_set_progressive_read_fn().  You can use
       any struct as the user_ptr (cast to a void pointer
       for the function call), and retrieve the pointer
       from inside the callbacks using the function

          png_get_progressive_ptr(png_ptr);

       which will return a void pointer, which you have
       to cast appropriately.
     */
    png_set_progressive_read_fn(png_ptr, (void *)user_ptr,
        info_callback, row_callback, end_callback);

    return 0;
 }

 /* A code fragment that you call as you receive blocks
   of data */
 int
 process_data(png_bytep buffer, png_uint_32 length)
 {
    if (setjmp(png_jmpbuf(png_ptr)))
    {
        png_destroy_read_struct(&png_ptr, &info_ptr,
           (png_infopp)NULL);
        return (ERROR);
    }

    /* This one's new also.  Simply give it a chunk
       of data from the file stream (in order, of
       course).  On machines with segmented memory
       models machines, don't give it any more than
       64K.  The library seems to run fine with sizes
       of 4K. Although you can give it much less if
       necessary (I assume you can give it chunks of
       1 byte, I haven't tried less then 256 bytes
       yet).  When this function returns, you may
       want to display any rows that were generated
       in the row callback if you don't already do
       so there.
     */
    png_process_data(png_ptr, info_ptr, buffer, length);
    return 0;
 }

 /* This function is called (as set by
    png_set_progressive_read_fn() above) when enough data
    has been supplied so all of the header has been
    read.
 */
 void
 info_callback(png_structp png_ptr, png_infop info)
 {
    /* Do any setup here, including setting any of
       the transformations mentioned in the Reading
       PNG files section.  For now, you _must_ call
       either png_start_read_image() or
       png_read_update_info() after all the
       transformations are set (even if you don't set
       any).  You may start getting rows before
       png_process_data() returns, so this is your
       last chance to prepare for that.
     */
 }

 /* This function is called when each row of image
    data is complete */
 void
 row_callback(png_structp png_ptr, png_bytep new_row,
    png_uint_32 row_num, int pass)
 {
    /* If the image is interlaced, and you turned
       on the interlace handler, this function will
       be called for every row in every pass.  Some
       of these rows will not be changed from the
       previous pass.  When the row is not changed,
       the new_row variable will be NULL.  The rows
       and passes are called in order, so you don't
       really need the row_num and pass, but I'm
       supplying them because it may make your life
       easier.

       For the non-NULL rows of interlaced images,
       you must call png_progressive_combine_row()
       passing in the row and the old row.  You can
       call this function for NULL rows (it will just
       return) and for non-interlaced images (it just
       does the memcpy for you) if it will make the
       code easier.  Thus, you can just do this for
       all cases:
     */

        png_progressive_combine_row(png_ptr, old_row,
          new_row);

    /* where old_row is what was displayed for
       previously for the row.  Note that the first
       pass (pass == 0, really) will completely cover
       the old row, so the rows do not have to be
       initialized.  After the first pass (and only
       for interlaced images), you will have to pass
       the current row, and the function will combine
       the old row and the new row.
    */
 }

 void
 end_callback(png_structp png_ptr, png_infop info)
 {
    /* This function is called after the whole image
       has been read, including any chunks after the
       image (up to and including the IEND).  You
       will usually have the same info chunk as you
       had in the header, although some data may have
       been added to the comments and time fields.

       Most people won't do much here, perhaps setting
       a flag that marks the image as finished.
     */
 }

IV. Das Schreiben

Viel davon ist dem Lesen sehr ähnlich. Jedoch wird alles Wichtiges hier wiederholt, so werden Sie sich ständig in der Lesen-Abteilung nicht umsehen müssen, um das Schreiben zu verstehen.

Einstellung

Sie werden die Eingabe/Ausgabe-Initialisierung tun wollen, bevor Sie in libpng so kommen, wenn es nicht arbeitet, haben Sie nichts, um aufzumachen. Wenn Sie die Standardeingabe/Ausgabe-Funktionen nicht verwenden, werden Sie sie durch kundenspezifische Schreiben-Funktionen ersetzen müssen. Sieh die Diskussion unter der Anpassung libpng.

   FILE *fp = fopen(file_name, "wb");
    if (!fp)
    {
       return (ERROR);
    }

Dann müssen png_struct und png_info alloziert und initialisiert werden. Weil diese beide relativ groß sein können, können Sie nicht diese auf dem Stapel speichern wollen, es sei denn, dass Sie Stapel-Raum haben, um zu sparen. Natürlich werden Sie überprüfen wollen, ob sie UNGÜLTIG zurückkehren. Wenn Sie auch lesen, werden Sie Ihre gelesene Struktur und Ihren nicht nennen wollen, Struktur beide "png_ptr" geschrieben; Sie können sie irgendetwas nennen, was Sie, wie "read_ptr" und "write_ptr" mögen. Schauen Sie auf pngtest.c zum Beispiel.

  png_structp png_ptr = png_create_write_struct
       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
        user_error_fn, user_warning_fn);
    if (!png_ptr)
       return (ERROR);

    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr)
    {
       png_destroy_write_struct(&png_ptr,
         (png_infopp)NULL);
       return (ERROR);
    }

Wenn Sie Ihre eigenen Arbeitsspeicherzuweisungsroutinen verwenden wollen, PNG_USER_MEM_SUPPORTED zu definieren und png_create_write_struct_2 () statt png_create_write_struct () zu verwenden:

  png_structp png_ptr = png_create_write_struct_2
       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
        user_error_fn, user_warning_fn, (png_voidp)
        user_mem_ptr, user_malloc_fn, user_free_fn);

Nachdem Sie diese Strukturen haben, werden Sie die Fehlerbehandlung aufstellen müssen. Wenn libpng auf einen Fehler stößt, erwartet er zu longjmp () zurück zu Ihrer Routine. Deshalb werden Sie setjmp () nennen und den png_jmpbuf (png_ptr) passieren müssen. Wenn Sie die Datei von verschiedenen Routinen schreiben, werden Sie den png_jmpbuf (png_ptr) jedes Mal aktualisieren müssen, wenn Sie eine neue Routine eingeben, die einen png_ * () Funktion nennen wird. Sieh Ihre Dokumentation von setjmp/longjmp für Ihren Bearbeiter für weitere Informationen über setjmp/longjmp. Sieh die Diskussion über die libpng Fehlerbehandlung in der Anpassung Libpng Abteilung unten für weitere Informationen über die libpng Fehlerbehandlung.

 if (setjmp(png_jmpbuf(png_ptr)))
    {
       png_destroy_write_struct(&png_ptr, &info_ptr);
       fclose(fp);
       return (ERROR);
    }
    ...
    return;

Wenn Sie die Kompliziertheit von setjmp/Longjmp-Problemen lieber vermeiden möchten, können Sie libpng mit PNG_SETJMP_NOT_SUPPORTED kompilieren, in welchem Fall Fehler auf einen Anruf zu PNG_ABORT () welch Verzug hinauslaufen werden () abzubrechen.

Jetzt müssen Sie den Produktionscode aufstellen. Der Verzug für libpng soll die C-Funktion fwrite () verwenden. Wenn Sie das verwenden, werden Sie eine gültige DATEI * in der Funktion png_init_io () passieren müssen. Seien Sie überzeugt, dass die Datei in der binären Weise geöffnet wird. Wieder, wenn Sie Schreiben-Daten auf eine andere Weise behandeln möchten, sieh die Diskussion über die libpng Eingabe/Ausgabe, die in der Anpassung Libpng Abteilung unten behandelt.

     png_init_io(png_ptr, fp);

Schreiben Sie Rückrufaktionen

An diesem Punkt können Sie eine Rückrufaktionsfunktion aufstellen, die genannt wird, nachdem jede Reihe geschrieben worden ist, den Sie verwenden können, um einen Fortschritt-Meter oder das ähnliche zu kontrollieren. Es wird in pngtest.c demonstriert. Sie müssen eine Funktion liefern

    void write_row_callback(png_ptr, png_uint_32 row,
       int pass);
    {
      /* put your code here */
    }

(Sie können ihm einen anderen Namen geben, den Sie statt "write_row_callback" mögen)

Um libpng über Ihre Funktion zu informieren, verwenden

     png_set_write_status_fn(png_ptr, write_row_callback);

Sie haben jetzt die Option des Änderns, wie die Kompressionsbibliothek laufen wird. Die folgenden Funktionen sind hauptsächlich für die Prüfung, aber können in einigen Fällen, wie nützlich sein, wenn Sie PNG Dateien äußerst schnell schreiben müssen und bereit sind, etwas Kompression aufzugeben, oder wenn Sie die maximale mögliche Kompression auf Kosten des langsameren Schreibens bekommen wollen. Wenn Sie keine speziellen Bedürfnisse in diesem Gebiet haben, lassen Sie die Bibliothek tun, was es will, diese Funktion überhaupt nicht nennend, weil es abgestimmt worden ist, um eine gute Geschwindigkeit/Verdichtungsverhältnis zu liefern. Der zweite Parameter zu png_set_filter () ist die Filtermethode, für die die einzigen gültigen Werte 0 (bezüglich des Julis 1999 PNG Spezifizierung, Version 1.2) oder 64 sind (wenn Sie einen PNG datastream schreiben, der in einem MNG datastream eingebettet werden soll). Der dritte Parameter ist eine Fahne, die anzeigt, welcher Filtertyp (En) für jeden scanline geprüft werden sollen. Sieh die PNG Spezifizierung für Details auf den spezifischen Filtertypen.

    /* turn on or off filtering, and/or choose
       specific filters.  You can use either a single
       PNG_FILTER_VALUE_NAME or the logical OR of one
       or more PNG_FILTER_NAME masks. */
    png_set_filter(png_ptr, 0,
       PNG_FILTER_NONE  | PNG_FILTER_VALUE_NONE |
       PNG_FILTER_SUB   | PNG_FILTER_VALUE_SUB  |
       PNG_FILTER_UP    | PNG_FILTER_VALUE_UP   |
       PNG_FILTER_AVE   | PNG_FILTER_VALUE_AVE  |
       PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH|
       PNG_ALL_FILTERS);

Wenn eine Anwendung starten und aufhören will, besondere Filter während der Kompression zu verwenden, sollte sie mit allen Filtern aufbrechen (um sicherzustellen, dass die vorherige Reihe von Pixeln gespeichert wird, im Falle dass sie später gebraucht hat), und dann fügen Sie hinzu und entfernen Sie sie nach dem Anfang der Kompression.

Wenn Sie einen PNG datastream schreiben, der in einem MNG datastream eingebettet werden soll, kann der zweite Parameter entweder 0 oder 64 sein.

Der png_set_compression_ * () die Funktionsschnittstelle zur zlib Kompressionsbibliothek, und sollte größtenteils ignoriert werden es sei denn, dass Sie wirklich wissen, was Sie tun. Der einzige allgemein nützliche Anruf ist png_set_compression_level (), welcher sich ändert, wie viel Zeit zlib für das Versuchen ausgibt, die Bilddaten zu komprimieren. Sieh die Kompressionsbibliothek (zlib.h und algorithm.txt, verteilt mit zlib) für Details auf den Kompressionsniveaus.

   /* set the zlib compression level */
    png_set_compression_level(png_ptr,
        Z_BEST_COMPRESSION);

    /* set other zlib parameters */
    png_set_compression_mem_level(png_ptr, 8);
    png_set_compression_strategy(png_ptr,
        Z_DEFAULT_STRATEGY);
    png_set_compression_window_bits(png_ptr, 15);
    png_set_compression_method(png_ptr, 8);
    png_set_compression_buffer_size(png_ptr, 8192)

extern PNG_EXPORT(void,png_set_zbuf_size)

Das Setzen des Inhalts des Infos für die Produktion

Sie müssen jetzt die png_info Struktur mit allen Daten ausfüllen, die Sie vor dem wirklichen Image schreiben möchten. Bemerken Sie, dass das einzige Ding, das Ihnen erlaubt wird, nach dem Image zu schreiben, die Textklötze und der Zeitklotz (bezüglich der PNG Spezifizierung 1.2, irgendwie) ist. Sieh png_write_end () und die letzte PNG Spezifizierung für weitere Informationen darüber. Wenn Sie ihnen vor dem Image schreiben möchten, sie jetzt, und Fahne dass Daten als gültig seiend auszufüllen. Wenn Sie bis die Daten warten wollen, füllen Sie sie bis png_write_end () nicht. Für alle Felder in png_info und ihren Datentypen, sieh png.h. Für Erklärungen dessen, was die Felder enthalten, sieh die PNG Spezifizierung.

Einige der wichtigeren Teile des png_info sind:

    png_set_IHDR(png_ptr, info_ptr, width, height,
       bit_depth, color_type, interlace_type,
       compression_type, filter_method)
    width          - holds the width of the image
                     in pixels (up to 2^31).
    height         - holds the height of the image
                     in pixels (up to 2^31).
    bit_depth      - holds the bit depth of one of the
                     image channels.
                     (valid values are 1, 2, 4, 8, 16
                     and depend also on the
                     color_type.  See also significant
                     bits (sBIT) below).
    color_type     - describes which color/alpha
                     channels are present.
                     PNG_COLOR_TYPE_GRAY
                        (bit depths 1, 2, 4, 8, 16)
                     PNG_COLOR_TYPE_GRAY_ALPHA
                        (bit depths 8, 16)
                     PNG_COLOR_TYPE_PALETTE
                        (bit depths 1, 2, 4, 8)
                     PNG_COLOR_TYPE_RGB
                        (bit_depths 8, 16)
                     PNG_COLOR_TYPE_RGB_ALPHA
                        (bit_depths 8, 16)

                     PNG_COLOR_MASK_PALETTE
                     PNG_COLOR_MASK_COLOR
                     PNG_COLOR_MASK_ALPHA

    interlace_type - PNG_INTERLACE_NONE or
                     PNG_INTERLACE_ADAM7
    compression_type - (must be
                     PNG_COMPRESSION_TYPE_DEFAULT)
    filter_method  - (must be PNG_FILTER_TYPE_DEFAULT
                     or, if you are writing a PNG to
                     be embedded in a MNG datastream,
                     can also be
                     PNG_INTRAPIXEL_DIFFERENCING)

    png_set_PLTE(png_ptr, info_ptr, palette,
       num_palette);
    palette        - the palette for the file
                     (array of png_color)
    num_palette    - number of entries in the palette

    png_set_gAMA(png_ptr, info_ptr, gamma);
    gamma          - the gamma the image was created
                     at (PNG_INFO_gAMA)

    png_set_sRGB(png_ptr, info_ptr, srgb_intent);
    srgb_intent    - the rendering intent
                     (PNG_INFO_sRGB) The presence of
                     the sRGB chunk means that the pixel
                     data is in the sRGB color space.
                     This chunk also implies specific
                     values of gAMA and cHRM.  Rendering
                     intent is the CSS-1 property that
                     has been defined by the International
                     Color Consortium
                     (http://www.color.org/).
                     It can be one of
                     PNG_sRGB_INTENT_SATURATION,
                     PNG_sRGB_INTENT_PERCEPTUAL,
                     PNG_sRGB_INTENT_ABSOLUTE, or
                     PNG_sRGB_INTENT_RELATIVE.


    png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr,
       srgb_intent);
    srgb_intent    - the rendering intent
                     (PNG_INFO_sRGB) The presence of the
                     sRGB chunk means that the pixel
                     data is in the sRGB color space.
                     This function also causes gAMA and
                     cHRM chunks with the specific values
                     that are consistent with sRGB to be
                     written.

    png_set_iCCP(png_ptr, info_ptr, name, compression_type,
                      profile, proflen);
    name            - The profile name.
    compression     - The compression type; always
                      PNG_COMPRESSION_TYPE_BASE for PNG 1.0.
                      You may give NULL to this argument to
                      ignore it.
    profile         - International Color Consortium color
                      profile data. May contain NULs.
    proflen         - length of profile data in bytes.

    png_set_sBIT(png_ptr, info_ptr, sig_bit);
    sig_bit        - the number of significant bits for
                     (PNG_INFO_sBIT) each of the gray, red,
                     green, and blue channels, whichever are
                     appropriate for the given color type
                     (png_color_16)

    png_set_tRNS(png_ptr, info_ptr, trans, num_trans,
       trans_values);
    trans          - array of transparent entries for
                     palette (PNG_INFO_tRNS)
    trans_values   - graylevel or color sample values of
                     the single transparent color for
                     non-paletted images (PNG_INFO_tRNS)
    num_trans      - number of transparent entries
                     (PNG_INFO_tRNS)

    png_set_hIST(png_ptr, info_ptr, hist);
                    (PNG_INFO_hIST)
    hist           - histogram of palette (array of
                     png_uint_16)

    png_set_tIME(png_ptr, info_ptr, mod_time);
    mod_time       - time image was last modified
                     (PNG_VALID_tIME)

    png_set_bKGD(png_ptr, info_ptr, background);
    background     - background color (PNG_VALID_bKGD)

    png_set_text(png_ptr, info_ptr, text_ptr, num_text);
    text_ptr       - array of png_text holding image
                     comments
    text_ptr[i].compression - type of compression used
                 on "text" PNG_TEXT_COMPRESSION_NONE
                           PNG_TEXT_COMPRESSION_zTXt
                           PNG_ITXT_COMPRESSION_NONE
                           PNG_ITXT_COMPRESSION_zTXt
    text_ptr[i].key   - keyword for comment.  Must contain
                 1-79 characters.
    text_ptr[i].text  - text comments for current
                         keyword.  Can be NULL or empty.
    text_ptr[i].text_length - length of text string,
                 after decompression, 0 for iTXt
    text_ptr[i].itxt_length - length of itxt string,
                 after decompression, 0 for tEXt/zTXt
    text_ptr[i].lang  - language of comment (NULL or
                         empty for unknown).
    text_ptr[i].translated_keyword  - keyword in UTF-8 (NULL
                         or empty for unknown).
    num_text       - number of comments

    png_set_sPLT(png_ptr, info_ptr, &palette_ptr,
       num_spalettes);
    palette_ptr    - array of png_sPLT_struct structures
                     to be added to the list of palettes
                     in the info structure.
    num_spalettes  - number of palette structures to be
                     added.

    png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y,
        unit_type);
    offset_x  - positive offset from the left
                     edge of the screen
    offset_y  - positive offset from the top
                     edge of the screen
    unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER

    png_set_pHYs(png_ptr, info_ptr, res_x, res_y,
        unit_type);
    res_x       - pixels/unit physical resolution
                  in x direction
    res_y       - pixels/unit physical resolution
                  in y direction
    unit_type   - PNG_RESOLUTION_UNKNOWN,
                  PNG_RESOLUTION_METER

    png_set_sCAL(png_ptr, info_ptr, unit, width, height)
    unit        - physical scale units (an integer)
    width       - width of a pixel in physical scale units
    height      - height of a pixel in physical scale units
                  (width and height are doubles)

    png_set_sCAL_s(png_ptr, info_ptr, unit, width, height)
    unit        - physical scale units (an integer)
    width       - width of a pixel in physical scale units
    height      - height of a pixel in physical scale units
                 (width and height are strings like "2.54")

    png_set_unknown_chunks(png_ptr, info_ptr, &unknowns,
       num_unknowns)
    unknowns          - array of png_unknown_chunk
                        structures holding unknown chunks
    unknowns[i].name  - name of unknown chunk
    unknowns[i].data  - data of unknown chunk
    unknowns[i].size  - size of unknown chunk's data
    unknowns[i].location - position to write chunk in file
                           0: do not write chunk
                           PNG_HAVE_IHDR: before PLTE
                           PNG_HAVE_PLTE: before IDAT
                           PNG_AFTER_IDAT: after IDAT

Das "Speicherstelle"-Mitglied wird automatisch gemäß gesetzt, was ein Teil der Ausgabedatei bereits geschrieben worden ist. Sie können seinen Wert nach dem Benennen png_set_unknown_chunks (), wie demonstriert, in pngtest.c ändern. Innerhalb von jeder der "Speicherstellen" sind die Klötze sequenced gemäß ihrer Position in der Struktur (d. h. der Wert von "i", der die Ordnung ist, in der der Klotz entweder von der Eingabedatei gelesen oder mit png_set_unknown_chunks definiert wurde).

Ein schnelles Wort über den Text und num_text. Text ist eine Reihe von png_text Strukturen. num_text ist die Anzahl von gültigen Strukturen in der Reihe. Jede png_text Struktur hält einen Sprachcode, ein Schlüsselwort, einen Textwert, und einen Kompressionstyp.

Die Kompressionstypen haben dieselben gültigen Anzahlen wie die Kompressionstypen der Bilddaten. Zurzeit ist die einzige gültige Anzahl Null. Jedoch können Sie Text entweder komprimiert oder unkomprimiert verschieden von Images speichern, die immer komprimiert werden müssen. So, wenn Sie den komprimierten Text nicht wollen, setzen Sie den Kompressionstyp auf PNG_TEXT_COMPRESSION_NONE. Weil Text und zTXt Klötze ein Sprachfeld nicht haben, wenn Sie PNG_TEXT_COMPRESSION_NONE oder PNG_TEXT_COMPRESSION_zTXt angeben, werden jeder Sprachcode oder übersetztes Schlüsselwort nicht ausgeschrieben.

Bis Text um 1000 Bytes herumkommt, ist es das Zusammendrücken davon nicht wert. Nachdem der Text zur Datei ausgeschrieben worden ist, wird der Kompressionstyp zu PNG_TEXT_COMPRESSION_NONE_WR oder PNG_TEXT_COMPRESSION_zTXt_WR gesetzt, so dass es wieder am Ende nicht ausgeschrieben wird (im Falle dass Sie png_write_end () mit demselben struct nennen.

Die Schlüsselwörter, die in der PNG Spezifizierung gegeben werden, sind:

  Title            Short (one line) title or
                     caption for image
    Author           Name of image's creator
    Description      Description of image (possibly long)
    Copyright        Copyright notice
    Creation Time    Time of original image creation
                     (usually RFC 1123 format, see below)
    Software         Software used to create the image
    Disclaimer       Legal disclaimer
    Warning          Warning of nature of content
    Source           Device used to create the image
    Comment          Miscellaneous comment; conversion
                     from other image format

Die Paare des Schlüsselwort-Textes arbeiten wie das. Schlüsselwörter sollten kurze einfache Beschreibungen dessen sein, worüber die Anmerkung ist. Einige typische Schlüsselwörter werden in der PNG Spezifizierung gefunden, als einige Empfehlungen auf Schlüsselwörtern ist. Sie können Schlüsselwörter in einer Datei wiederholen. Sie können sogar einen Text vor dem Image und einigen danach schreiben. Zum Beispiel können Sie eine Beschreibung des Images vor dem Image stellen, aber die Verzichterklärung bis verlassen wollen, so müssen Zuschauer, die über Modemverbindungen arbeiten, nicht auf die Verzichterklärung warten, um das Modem durchzusehen, bevor sie starten, das Image zu sehen. Schließlich sollten Schlüsselwörter volle Wörter, nicht Abkürzungen sein. Schlüsselwörter und Text sind im ISO 8859-1 (lateinischer 1) Zeichenmenge (eine Obermenge von regelmäßigem ASCII) und können nicht NUL Zeichen enthalten, und sollten nicht Kontrolle oder andere nicht druckfähige Zeichen enthalten. Um die Anmerkungen weit lesbar zu machen, stecken Sie mit grundlegendem ASCII, und Maschine spezifische Zeichenmenge-Erweiterungen wie die Zeichenmenge des der IBM PCs zu vermeiden. Das Schlüsselwort muss da sein, aber Sie können die Textfolge auf nichtkomprimierten Paaren weglassen. Komprimierte Paare müssen eine Textfolge haben, weil nur die Textfolge irgendwie komprimiert wird, so würde die Kompression sinnlos sein.

PNG Support-Modifizierungszeit über die png_time Struktur. Zwei Umwandlungsroutinen, werden png_convert_from_time_t () für time_t und png_convert_from_struct_tm () für struct tm zur Verfügung gestellt. Die time_t Routine verwendet gmtime (). Sie müssen keinen von diesen verwenden, aber wenn Sie die png_time Struktur direkt ausfüllen möchten, sollten Sie die Zeit mit der koordinierten Weltzeit (WEZ), wenn möglich, statt Ihrer Ortszeit zur Verfügung stellen. Bemerken Sie, dass die Jahr-Anzahl das volle Jahr ist (z.B 1998, aber nicht 98 - ist PNG entgegenkommendes Jahr 2000!), und diese Monate fangen mit 1 an.

Wenn Sie die Zeit der ursprünglichen Bildentwicklung speichern wollen, sollten Sie einen Klartext-Klotz mit dem "Entwicklung" Zeitschlüsselwort verwenden. Das ist notwendig, weil die "Entwicklungszeit" eines PNG Images je nachdem etwas vage ist, ob Sie die PNG Datei, die Zeit meinen, wurde das Image in einem Non-PNG-Format, noch Foto geschaffen, von dem das Image, oder vielleicht der Gegenstand selbst gescannt wurde. Um maschinenlesbare Daten zu erleichtern, wird es empfohlen, dass der "Entwicklung" Zeittextklotz RFC 1123 Format-Daten verwendet (z.B "am 22. Mai 1997 18:07:10 WEZ"), obwohl das nicht eine Voraussetzung ist. Verschieden vom Zeitklotz, wie man erwartet, wird der "Entwicklung" Zeittextklotz durch die Software nicht automatisch geändert. Um den Gebrauch von RFC 1123 Daten zu erleichtern, wird eine Funktion png_convert_to_rfc1123 (png_timep) zur Verfügung gestellt, um sich von der PNG Zeit zu einer RFC 1123-Format-Schnur umzuwandeln.

Das Schreiben unbekannter Klötze

Sie können die png_set_unknown_Chunks-Funktion verwenden, Klötze für das Schreiben Schlange zu stehen. Sie geben ihm einen Klotz-Namen, Ausgangsdaten, und eine Größe; es ist alles, was es dazu gibt. Die Klötze werden durch den folgenden folgenden png_write_info_before_PLTE, png_write_info, oder png_write_End-Funktion geschrieben. Irgendwelche in die Info-Struktur-Liste des unbekannten Klotzes vorher gelesenen Klötze werden auch in einer Folge ausgeschrieben, die die Einrichtung der PNG Spezifizierung von Regeln befriedigt.

Die auf höchster Ebene schreiben Schnittstelle

An diesem Punkt gibt es zwei Wege weiterzugehen; durch das auf höchster Ebene schreiben, dass Schnittstelle, oder durch eine Folge auf niedriger Stufe Operationen schreiben. Sie können die Schnittstelle auf höchster Ebene verwenden, wenn Ihre Bilddaten in der Info-Struktur da sind. Alle definierten Produktionstransformationen werden erlaubt, durch die folgenden Masken ermöglicht.

 PNG_TRANSFORM_IDENTITY      No transformation
    PNG_TRANSFORM_PACKING       Pack 1, 2 and 4-bit samples
    PNG_TRANSFORM_PACKSWAP      Change order of packed
                                pixels to LSB first
    PNG_TRANSFORM_INVERT_MONO   Invert monochrome images
    PNG_TRANSFORM_SHIFT         Normalize pixels to the
                                sBIT depth
    PNG_TRANSFORM_BGR           Flip RGB to BGR, RGBA
                                to BGRA
    PNG_TRANSFORM_SWAP_ALPHA    Flip RGBA to ARGB or GA
                                to AG
    PNG_TRANSFORM_INVERT_ALPHA  Change alpha from opacity
                                to transparency
    PNG_TRANSFORM_SWAP_ENDIAN   Byte-swap 16-bit samples
    PNG_TRANSFORM_STRIP_FILLER  Strip out filler bytes.

Wenn Sie gültige Bilddaten in der Info-Struktur haben (Sie können png_set_rows () verwenden, um Bilddaten in der Info-Struktur zu stellen), tun Sie einfach das:

    png_write_png(png_ptr, info_ptr, png_transforms, NULL)

wo png_transforms eine ganze Zahl ist, die das logische ODER von einem Satz von Transformationsfahnen enthält. Dieser Anruf ist zu png_write_info gleichwertig (), folgte dem Satz von Transformationen, die durch die umgestalten Maske, dann png_write_image (), und schließlich png_write_end () angezeigt sind.

(Der Endparameter dieses Anrufs wird noch nicht verwendet. Eines Tages könnte es zu durch eine zukünftige Produktion erforderlichen Transformationsparametern hinweisen verwandeln sich.)

Die auf niedriger Stufe schreiben Schnittstelle

Wenn Sie die auf niedriger Stufe Route statt dessen gehen, sind Sie jetzt bereit, der ganzen Dateiinformation bis zu den wirklichen Bilddaten zu schreiben. Sie tun das mit einem Anruf png_write_info ().

    png_write_info(png_ptr, info_ptr);

Bemerken Sie, dass es eine Transformation gibt, die Sie vorher png_write_info () können tun müssen. In PNG Dateien ist der Alfakanal in einem Image das Niveau der Undurchsichtigkeit. Wenn Ihre Daten als ein Niveau der Durchsichtigkeit geliefert werden, können Sie den Alfakanal umkehren, bevor Sie es schreiben, so dass 0 völlig durchsichtig ist und 255 (in 8 Bit oder paletted Images) oder 65535 (in 16 Bitbildern), damit völlig undurchsichtig ist

  png_set_invert_alpha(png_ptr);

Das muss vorher png_write_info () statt später mit den anderen Transformationen erscheinen, weil im Fall von paletted Images die tRNS Klotz-Daten umgekehrt werden müssen, bevor der tRNS Klotz geschrieben wird. Wenn Ihr Image nicht ein paletted Image, die tRNS Daten ist (welcher in solchen Fällen eine einzelne Farbe vertritt, die als durchsichtig zu machen ist), wird nicht geändert zu werden brauchen, und Sie können diese Transformation nach Ihrem png_write_info () Anruf sicher tun.

Wenn Sie einen privaten Klotz schreiben müssen, dass Sie vor dem PLTE Klotz erscheinen wollen, wenn PLTE da ist, können Sie das PNG Info in zwei Schritten schreiben, und Code einfügen, um Ihren eigenen Klotz zwischen ihnen zu schreiben:

  png_write_info_before_PLTE(png_ptr, info_ptr);
    png_set_unknown_chunks(png_ptr, info_ptr, ...);
    png_write_info(png_ptr, info_ptr);

Nachdem Sie die Dateiinformation geschrieben haben, können Sie die Bibliothek aufstellen, um irgendwelche speziellen Transformationen der Bilddaten zu behandeln. Die verschiedenen Wege, die Daten umzugestalten, werden in der Ordnung beschrieben, dass sie vorkommen sollten. Das ist wichtig, weil einige von diesen den Farbentyp and/or Bit-Tiefe der Daten ändern, und einige andere nur an bestimmten Farbentypen und Bit-Tiefen arbeiten. Wenn auch jede Transformation überprüft, um zu sehen, ob sie Daten hat, mit denen sie etwas tun kann, sollten Sie sich überzeugen, um nur eine Transformation zu ermöglichen, wenn es für die Daten gültig sein wird. Tauschen Sie zum Beispiel rot und blau auf grayscale Daten nicht.

PNG Dateien speichern RGB in 3 oder 6 Bytes gepackte Pixel. Dieser Code sagt der Bibliothek, Eingangsdaten abzuziehen, der 4 oder 8 Bytes pro Pixel unten zu 3 oder 6 Bytes hat (oder ziehen Sie 2 oder 4 Byte grayscale+filler Daten zu 1 oder 2 Bytes pro Pixel ab).

   png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);

wo 0 unbenutzt ist, und die Speicherstelle entweder PNG_FILLER_BEFORE oder PNG_FILLER_AFTER, abhängig davon ist, ob das Füllzeichen im Pixel XRGB oder RGBX gespeichert wird.

PNG Dateien packen Pixel von Bit-Tiefen 1, 2, und 4 in ebenso kleine Bytes ein, wie sie können, zum Beispiel, 8 Pixel pro Byte für 1-Bit-Dateien hinauslaufend. Wenn die Daten an 1 Pixel pro Byte geliefert werden, verwenden Sie diesen Code, der die Pixel in ein einzelnes Byte richtig einpacken wird:

     png_set_packing(png_ptr);

PNG Dateien reduzieren mögliche Bit-Tiefen auf 1, 2, 4, 8, und 16. Wenn Ihre Daten von einer anderen Bit-Tiefe sind, können Sie einen sBIT Klotz in die Datei schreiben, so dass Decoder die ursprünglichen Daten, wenn gewünscht, wieder erlangen können.

  /* Set the true bit depth of the image data */
    if (color_type & PNG_COLOR_MASK_COLOR)
    {
        sig_bit.red = true_bit_depth;
        sig_bit.green = true_bit_depth;
        sig_bit.blue = true_bit_depth;
    }
    else
    {
        sig_bit.gray = true_bit_depth;
    }
    if (color_type & PNG_COLOR_MASK_ALPHA)
    {
        sig_bit.alpha = true_bit_depth;
    }

    png_set_sBIT(png_ptr, info_ptr, &sig_bit);

Wenn die Daten im Reihe-Puffer in kurzer Zeit Tiefe außer einem unterstütztem durch PNG gespeichert werden (z.B 3-Bit-Daten in der Reihe 0-7 für einen 4-Bit-PNG), wird das klettern die Werte, um zu scheinen, die richtige Bit-Tiefe zu sein, ist als durch PNG erforderlich.

    png_set_shift(png_ptr, &sig_bit);

PNG Dateien speichern 16-Bit-Pixel in der Netzwerksbyte-Ordnung (groß-endian, d. h.. die meisten bedeutenden Bit zuerst). Dieser Code würde verwendet, wenn sie der andere Weg geliefert werden (wenig-endian, d. h. am wenigsten bedeutende Bit zuerst, der Weg, wie PCs sie speichern):

     if (bit_depth > 8)
       png_set_swap(png_ptr);

Wenn Sie einpacken-Bildpunktabbilder (1, 2, oder 4 Bit/Pixel) verwenden, und Sie die Ordnung ändern müssen, sind die Pixel in Bytes gepackt, Sie können verwenden:

    if (bit_depth < 8)
       png_set_packswap(png_ptr);

PNG Dateien speichern 3 Farbenpixel in der roten, grünen, blauen Ordnung. Dieser Code würde verwendet, wenn sie als blau, grün, rot geliefert werden:

    png_set_bgr(png_ptr);

PNG Dateien beschreiben monochrom als schwarz, Null und weiß seiend, ein seiend. Dieser Code würde verwendet, wenn die Pixel damit geliefert werden, kehrte (schwarz um, ein und weiß seiend, Null seiend):

      png_set_invert_mono(png_ptr);

Schließlich können Sie Ihre eigene Transformationsfunktion schreiben, wenn keiner der vorhandenen Ihren Bedarf deckt. Das wird getan, eine Rückrufaktion damit setzend

    png_set_write_user_transform_fn(png_ptr,
       write_transform_fn);

Sie müssen die Funktion liefern

     void write_transform_fn(png_ptr ptr, row_info_ptr
       row_info, png_bytep data)

Sieh pngtest.c für ein Arbeitsbeispiel. Ihre Funktion wird genannt vor einigen der anderen Transformationen werden bearbeitet.

Sie können auch einen Adressenverweis zu einer Benutzerstruktur für den Gebrauch durch Ihre Rückrufaktionsfunktion aufstellen.

     png_set_user_transform_info(png_ptr, user_ptr, 0, 0);

Der user_channels und die user_depth Parameter dieser Funktion werden ignoriert schreibend; Sie können sie auf die Null, wie gezeigt, setzen.

Sie können den Adressenverweis über die Funktion png_get_user_transform_ptr () abrufen. Zum Beispiel:

     voidp write_user_transform_ptr =
       png_get_user_transform_ptr(png_ptr);

Es ist möglich, Libpng-Erröten irgendwelcher während der Produktion, entweder manuell, oder automatisch zu haben, nachdem eine bestimmte Anzahl von Linien geschrieben worden ist. Um die Produktion zu spülen, verströmen einen einzelnen Zeitanruf:

     png_write_flush(png_ptr);

und libpng zu haben, spülen den Produktionsstrom regelmäßig, nachdem eine bestimmte Anzahl von scanlines geschrieben worden ist, rufen Sie:

    png_set_flush(png_ptr, nrows);

Bemerken Sie, dass die Entfernung zwischen Reihen vom letzten Mal png_write_flush ist (), wurde oder die erste Reihe des Images genannt, wenn es nie genannt worden ist. So, wenn Sie 50 Linien, und dann png_set_flush 25 schreiben, wird es die Produktion auf dem folgenden scanline, und alle 25 Linien danach spülen, es sei denn, dass png_write_flush () genannt wird, bevor noch 25 Linien geschrieben worden sind. Wenn nrows zu klein ist (weniger als ungefähr 10 Linien für ein 640 Pixel breites RGB Image), kann die Bildkompression merklich abnehmen (obwohl das für Echtzeitanwendungen annehmbar sein kann). Seltene Spülung wird nur die Kompressionsleistung durch einiges Prozent über Images erniedrigen, die Spülung nicht verwenden.

Das Schreiben der Bilddaten

So ist's recht! für die Transformationen. Jetzt können Sie die Bilddaten schreiben. Der einfachste Weg zu tun ist das in einem Funktionsaufruf. Wenn Sie das ganze Image im Speicher haben, können Sie gerade png_write_image nennen (), und libpng wird das Image schreiben. Sie werden in einer Reihe von Adressenverweisen zu jeder Reihe gehen müssen. Diese Funktion behandelt automatisch das Verflechten, so brauchen Sie nicht png_set_interlace_handling () zu nennen oder diese Funktion mehrmals, oder einige dieses anderen mit png_write_rows notwendigen Zeugs () zu nennen.

   png_write_image(png_ptr, row_pointers);
 

wo row_pointers ist:

   png_byte *row_pointers[height];

Sie können zur Leere oder Rotforelle hinweisen, oder was auch immer Sie für Pixel verwenden.

Wenn Sie das ganze Image sofort nicht schreiben wollen, können Sie png_write_rows () stattdessen verwenden. Wenn die Datei nicht verflochten wird, ist das einfach:

     png_write_rows(png_ptr, row_pointers,
       number_of_rows);

row_pointers ist dasselbe als im png_write_image () Anruf.

Wenn Sie gerade eine Reihe auf einmal schreiben, können Sie das mit einem einzelnen row_pointer statt einer Reihe von row_pointers tun:

     png_bytep row_pointer = row;

    png_write_row(png_ptr, row_pointer);

Wenn die Datei verflochten wird, können Dinge mehr viel kompliziert werden. Das einzige zurzeit (bezüglich der PNG Spezifizierungsversion 1.2, datierter Juli 1999) das definierte sich verflechtende Schema für PNG Dateien ist das "Adam7"-Zwischenzeile-Schema, das ein Image in sieben kleinere Images der unterschiedlichen Größe bricht. libpng wird diese Images für Sie bauen, oder Sie können sie selbst tun. Wenn Sie sie selbst bauen wollen, sieh die PNG Spezifizierung für Details der Pixel, wenn zu schreiben.

Wenn Sie nicht wollen, dass libpng die sich verflechtenden Details behandelt, verwenden Sie gerade png_set_interlace_handling () und nennen Sie png_write_rows () die richtige Anzahl von Zeiten, um alle sieben Subimages zu schreiben.

Wenn Sie wollen, dass libpng die Subimages baut, nennen Sie das, bevor Sie starten, irgendwelche Reihen zu schreiben:

   number_of_passes =
       png_set_interlace_handling(png_ptr);

Das wird die Anzahl von erforderlichen Pässen zurückgeben. Zurzeit ist das sieben, aber kann sich ändern, wenn ein anderer Zwischenzeile-Typ hinzugefügt wird.

Dann schreiben Sie das ganze Image number_of_passes Zeiten.

   png_write_rows(png_ptr, row_pointers,
       number_of_rows);

Weil einige dieser Reihen nicht verwendet werden, und so sofort zurückkehren, können Sie über das Verflechten in der PNG Spezifizierung lesen, und nur die Reihen aktualisieren wollen, die wirklich verwendet werden.

Das Vollenden eines folgenden schreibt

Nachdem Sie beendet werden, das Image schreibend, sollten Sie beenden, die Datei zu schreiben. Wenn Sie sich für das Schreiben von Anmerkungen oder Zeit interessieren, sollten Sie einen passend gefüllten png_info Adressenverweis passieren. Wenn Sie sich nicht interessieren, können Sie UNGÜLTIG gehen.

    png_write_end(png_ptr, info_ptr);

Wenn Sie getan werden, können Sie den ganzen Speicher befreien, der durch libpng wie das verwendet ist:

    png_destroy_write_struct(&png_ptr, &info_ptr);

Es ist auch dazu möglich einzeln befreien die info_ptr Mitglieder, die zur libpng-allozierten Speicherung mit der folgenden Funktion hinweisen:

   png_free_data(png_ptr, info_ptr, mask, seq)
    mask  - identifies data to be freed, a mask
            containing the logical OR of one or
            more of
              PNG_FREE_PLTE, PNG_FREE_TRNS,
              PNG_FREE_HIST, PNG_FREE_ICCP,
              PNG_FREE_PCAL, PNG_FREE_ROWS,
              PNG_FREE_SCAL, PNG_FREE_SPLT,
              PNG_FREE_TEXT, PNG_FREE_UNKN,
            or simply PNG_FREE_ALL
    seq   - sequence number of item to be freed
            (-1 for all items)

Diese Funktion kann sicher genannt werden, als die relevante Speicherung bereits befreit worden ist, oder noch nicht alloziert worden ist, oder vom Benutzer und nicht durch libpng alloziert wurde, und in jenen Fällen wird nichts tun. Der "seq" Parameter wird ignoriert, wenn nur einem Artikel des ausgewählten Datentyps, wie PLTE, erlaubt wird. Wenn "seq" nicht-1 ist, und vielfachen Sachen für den Datentyp erlaubt wird, der in der Maske, wie Text oder sPLT identifiziert ist, wird nur der n'th Artikel in der Struktur befreit, wo n "seq" ist.

Wenn Sie Daten wie eine Palette allozierten, in der Sie zu libpng mit png_set_ * gingen, müssen Sie nicht es bis kurz bevor dem Anruf png_destroy_write_struct () befreien.

Das Verzug-Verhalten ist nur, Daten zu befreien, der innerlich durch libpng alloziert wurde. Das kann geändert werden, so dass libpng die Daten nicht befreien wird, oder so dass er Daten befreien wird, der vom Benutzer mit png_malloc () oder png_zalloc () alloziert wurde und in über einen png_set_ * () Funktion, damit ging

    png_data_freer(png_ptr, info_ptr, freer, mask)
    mask   - which data elements are affected
             same choices as in png_free_data()
    freer  - one of
               PNG_DESTROY_WILL_FREE_DATA
               PNG_SET_WILL_FREE_DATA
               PNG_USER_WILL_FREE_DATA

Zum Beispiel, um Verantwortung für einige Daten von einer gelesenen Struktur bis eine schreiben Struktur zu übertragen, konnten Sie verwenden

 png_data_freer(read_ptr, read_info_ptr,
       PNG_USER_WILL_FREE_DATA,
       PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)
    png_data_freer(write_ptr, write_info_ptr,
       PNG_DESTROY_WILL_FREE_DATA,
       PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)

dadurch kurz wiederzuteilende Verantwortung, um dem Benutzer zu befreien, aber sofort später es noch einmal der write_Destroy-Funktion wiederzuzuteilen. Das getan, würde es dann sicher sein, die gelesene Struktur zu zerstören und fortzusetzen, den PLTE, tRNS, und die hIST Daten in der schreiben Struktur zu verwenden.

Diese Funktion betrifft nur Daten, der bereits alloziert worden ist. Sie können diese Funktion vor dem Benennen nach dem png_set_ * () Funktionen nennen zu kontrollieren, ob der Benutzer oder png_destroy_ * () die Daten befreien sollen. Wenn der Benutzer Verantwortung für libpng-allozierte Daten annimmt, muss die Anwendung png_free () verwenden, um sie zu befreien, und wenn der Benutzer Verantwortung libpng für Daten überträgt, die der Benutzer alloziert hat, muss der Benutzer png_malloc () oder png_zalloc () verwendet haben, um sie zu allozieren.

Wenn Sie text_ptr.text, text_ptr.lang, und text_ptr.translated_keyword getrennt allozierten, übertragen Sie Verantwortung nicht, um text_ptr zu libpng zu befreien, weil, wenn libpng eine png_text Struktur füllt, es diese Mitglieder mit dem Schlüsselmitglied verbindet, und png_free_data () nur text_ptr.key befreien wird. Ähnlich, wenn Sie Verantwortung für free'ing text_ptr von libpng bis Ihre Anwendung übertragen, muss Ihre Anwendung nicht jene Mitglieder getrennt befreien. Für ein kompakteres Beispiel, ein PNG Image zu schreiben, sieh die Datei example.c.

V. Ändern/Anpassung libpng:

Es gibt drei Probleme hier. Das erste ändert sich, wie libpng Standardsachen wie Arbeitsspeicherzuweisung, Eingang/Produktion, und Fehlerbehandlung macht. Die zweiten Geschäfte mit mehr komplizierten Dingen wie das Hinzufügen neuer Klötze, Hinzufügen neuer Transformationen, und allgemein Ändern, wie libpng arbeitet. Beide von denjenigen sind Kompilierungszeit-Probleme; d. h. sie sind allgemein zurzeit entschlossen der Code wird geschrieben, und es gibt selten ein Bedürfnis, den Benutzer mit einem Mittel des Änderns von ihnen zu versorgen. Das dritte ist ein Laufzeitproblem: Auswahl zwischen und/oder Einstimmung von demjenigen oder mehr abwechselnden Versionen rechenbetont intensiver Routinen; spezifisch, optimierter Assembler (und deshalb Bearbeiter - und Plattform-Abhängiger) Versionen.

Arbeitsspeicherzuweisung, Eingang/Produktion, und Fehlerbehandlung

Die ganze Arbeitsspeicherzuweisung, Eingang/Produktion, und Fehlerbehandlung in libpng geht Rückrufaktionen durch, die Benutzer-settable sind. Die Verzug-Routinen sind in pngmem.c, pngrio.c, pngwio.c, und pngerror.c beziehungsweise. Um diese Funktionen zu ändern, nennen Sie den passenden png_set_*_fn () Funktion.

Arbeitsspeicherzuweisung wird durch die Funktionen png_malloc () und png_free () getan. Diese nennen zurzeit gerade den Standard C Funktionen. Wenn Ihre Adressenverweise mehr dann auf 64 Kilobyte auf einmal nicht zugreifen können, werden Sie MAXSEG_64K in zlib.h setzen wollen. Da es unwahrscheinlich ist, dass sich die Methode, Arbeitsspeicherzuweisung auf einer Plattform zu behandeln, zwischen Anwendungen ändern wird, müssen diese Funktionen in der Bibliothek während der Übersetzung modifiziert werden. Wenn Sie es vorziehen, eine verschiedene Methode zu verwenden, Daten zu allozieren und zu befreien, können Sie png_create_read_struct_2 () oder png_create_write_struct_2 () verwenden, um Ihre eigenen Funktionen, wie beschrieben, oben zu registrieren.

Diese Funktionen stellen auch einen leeren Adressenverweis zur Verfügung, der darüber abgerufen werden kann

     mem_ptr=png_get_mem_ptr(png_ptr);

Ihre Ersatzspeicherfunktionen müssen Prototypen wie folgt haben:

    png_voidp malloc_fn(png_structp png_ptr,
       png_size_t size);
    void free_fn(png_structp png_ptr, png_voidp ptr);

Ihr malloc_fn () sollte UNGÜLTIG im Falle des Misserfolgs zurückkehren. Der png_malloc () Funktion wird png_error nennen (), wenn es eine NULL vom Systemspeicherverteiler oder von Ihrem Ersatz malloc_fn () erhält.

Der Eingang/Produktion in libpng wird durch png_read () und png_write getan (), welche zurzeit gerade fread () und fwrite () nennen. Die DATEI * wird in png_struct gespeichert und wird über png_init_io () initialisiert. Wenn Sie die Methode der Eingabe/Ausgabe ändern möchten, liefert die Bibliothek Rückrufaktionen, die Sie durch die Funktion png_set_read_fn () und png_set_write_fn () in der Durchlaufzeit setzen können, anstatt den png_init_io () Funktion zu nennen. Diese Funktionen stellen auch einen leeren Adressenverweis zur Verfügung, der über die Funktion png_get_io_ptr () abgerufen werden kann. Zum Beispiel:

   png_set_read_fn(png_structp read_ptr,
        voidp read_io_ptr, png_rw_ptr read_data_fn)

    png_set_write_fn(png_structp write_ptr,
        voidp write_io_ptr, png_rw_ptr write_data_fn,
        png_flush_ptr output_flush_fn);

    voidp read_io_ptr = png_get_io_ptr(read_ptr);
    voidp write_io_ptr = png_get_io_ptr(write_ptr);

Die Ersatzeingabe/Ausgabe-Funktionen müssen Prototypen wie folgt haben:

    void user_read_data(png_structp png_ptr,
        png_bytep data, png_size_t length);
    void user_write_data(png_structp png_ptr,
        png_bytep data, png_size_t length);
    void user_flush_data(png_structp png_ptr);

UNGÜLTIG für das gelesene liefernd, schreiben Sie, oder Erröten-Funktionen werfen sie zum Verwenden des Verzugs C Strom-Funktionen zurück. Es ist ein Fehler, von einem schreiben Strom, und umgekehrt zu lesen.

Die Fehlerbehandlung in libpng wird durch png_error () und png_warning () getan. Durch png_error behandelte Fehler () sind tödlich, bedeutend, dass png_error () zu seinem Anrufer nie zurückkehren sollte. Zurzeit wird das über setjmp () und longjmp () behandelt (es sei denn, dass Sie libpng mit PNG_SETJMP_NOT_SUPPORTED kompiliert haben, in welchem Fall es über PNG_ABORT ()) behandelt wird, aber Sie konnten das ändern, um Sachen wie Ausgang zu machen (), wenn Sie wünschen sollten.

Auf nichtunbehebbaren Fehlern, png_warning () wird genannt, um eine Warnungsnachricht zu drucken, und dann Umsatz zum Benennen-Code zu kontrollieren. Standardmäßig drucken png_error () und png_warning () eine Nachricht auf stderr über fprintf () es sei denn, dass die Bibliothek mit definiertem PNG_NO_CONSOLE_IO kompiliert wird (weil Sie die Nachrichten nicht wollen), oder definierter PNG_NO_STDIO (weil fprintf () nicht verfügbar ist). Wenn Sie das Verhalten der Fehlerfunktionen ändern möchten, werden Sie Ihre eigenen Nachrichtenrückrufaktionen aufstellen müssen. Diese Funktionen werden normalerweise zurzeit geliefert, dass der png_struct geschaffen wird. Es ist auch möglich, Fehler und Warnungen zu Ihren eigenen Ersatzfunktionen umzuadressieren, nachdem png_create_*_struct () genannt worden ist rufend:

  png_set_error_fn(png_structp png_ptr,
        png_voidp error_ptr, png_error_ptr error_fn,
        png_error_ptr warning_fn);

    png_voidp error_ptr = png_get_error_ptr(png_ptr);

Wenn UNGÜLTIG entweder für error_fn oder für warning_fn geliefert wird, dann wird die libpng Verzug-Funktion verwendet, fprintf () und/oder longjmp rufend (), wenn auf ein Problem gestoßen wird. Die Ersatzfehlerfunktionen sollten Parameter wie folgt haben:

   void user_error_fn(png_structp png_ptr,
        png_const_charp error_msg);
    void user_warning_fn(png_structp png_ptr,
        png_const_charp warning_msg);

Die Motivation hinter dem Verwenden setjmp () und longjmp () ist der C ++ Werfen und Fang-Ausnahmebehandlungsmethoden. Das macht den Code viel leichter zu schreiben, weil es kein Bedürfnis gibt, jeden Rückcode jedes Funktionsaufrufs zu überprüfen. Jedoch gibt es einige Unklarheiten über den Status von lokalen Variablen nach einem longjmp, so kann der Benutzer über das Tun von irgendetwas sorgfältig sein wollen, nachdem setjmp Nichtnull außer dem Zurückbringen selbst zurückgibt. Befragen Sie Ihre Bearbeiter-Dokumentation für mehr Details. Für eine alternative Annäherung können Sie die "cexcept" Möglichkeit verwenden mögen (sieh http://cexcept.sourceforge.net/).

Kundenspezifische Klötze

Wenn Sie lesen oder kundenspezifische Klötze schreiben müssen, können Sie tiefer in den Libpng-Code werden müssen. Die Bibliothek hat jetzt Mechanismen, um Klötze des unbekannten Typs zu speichern und zu schreiben; Sie können sogar Rückrufaktionen für kundenspezifische Klötze erklären. Hoewver, das kann nicht gut genug sein, wenn der Bibliothekscode selbst über Wechselwirkungen zwischen Ihrem Klotz und vorhandenen 'inneren' Klötzen wissen muss.

Wenn Sie einen neuen inneren Klotz schreiben müssen, lesen Sie zuerst die PNG Spezifizierung. Erwerben Sie ein erstes Niveau des Verstehens dessen, wie es arbeitet. Schenken Sie besondere Aufmerksamkeit den Abteilungen, die Klotz-Namen beschreiben, und darauf schauen, wie andere Klötze entworfen wurden, so können Sie Sachen ähnlich machen. Überprüfen Sie zweitens die Abteilungen von libpng, die lesen und Klötze schreiben. Versuchen Sie, einen Klotz zu finden, der Ihrig ähnlich ist und es als eine Themenvorlage zu verwenden. Mehr Details können in den Anmerkungen innerhalb des Codes gefunden werden. Es ist am besten, unbekannte Klötze in einer allgemeinen Methode über Rückrufaktionsfunktionen zu behandeln, statt, libpng Funktionen modifizierend.

Wenn Sie Ihre eigene Transformation für die Daten schreiben möchten, den Teil des Codes durchzuschauen, der die Transformationen tut, und einige der einfacheren überprüft, um eine Idee davon zu bekommen, wie sie arbeiten. Versuchen Sie, eine ähnliche Transformation zu demjenigen zu finden, den Sie hinzufügen und von davon kopieren wollen. Mehr Details können in den Anmerkungen innerhalb des Codes selbst gefunden werden.

Das Konfigurieren für 16-Bit-Plattformen

Sie werden in zconf.h blicken wollen, um zlib zu sagen (und so libpng), dass es mehr dann 64 Kilobyte auf einmal nicht allozieren kann. Selbst wenn Sie, der Speicher können, nicht zugänglich zu sein. So beschränken Sie zlib und libpng zu 64 Kilobyte, MAXSEG_64K definierend.

Das Konfigurieren für DOS

Für DOS-Benutzer, die nur Zugang zum niedrigeren 640 Kilobyte haben, werden Sie den Speichergebrauch von zlib über einen png_set_compression_mem_level () Anruf beschränken müssen. Sieh zlib.h oder zconf.h in der zlib Bibliothek für mehr Information.

Das Konfigurieren für das Mittlere Modell

Der Support von Libpng für das mittlere Modell ist auf den meisten populären Bearbeitern geprüft worden. Stellen Sie sicher, dass MAXSEG_64K definiert wird, wird USE_FAR_KEYWORD definiert, und wird WEIT zu weit in pngconf.h definiert, und Sie sollten alle gesetzt werden. Alles in der Bibliothek (abgesehen von der Struktur von zlib) erwartet weite Daten. Sie müssen den typedefs mit dem p oder den Seiten auf dem Ende für Adressenverweise verwenden (oder mindestens auf sie schauen und sorgfältig sein). Machen Sie Zeichen, dass die Reihen von Daten als png_bytepp definiert werden, der eine nicht unterzeichnete Rotforelle weit * weit * ist.

Das Konfigurieren für gui/windowing Plattformen:

Sie werden neuen Fehler und Warnung von Funktionen schreiben müssen, die die GUI-Schnittstelle, wie beschrieben, vorher verwenden, und sie veranlassen, der Fehler und die Warnung von Funktionen zurzeit zu sein, dass png_create_*_struct () genannt wird, um sie verfügbar während der Struktur-Initialisierung zu haben. Sie können später über png_set_error_fn () geändert werden. Auf einigen Bearbeitern können Sie auch die Speicherverteiler (png_malloc, usw.) ändern müssen.

Das Konfigurieren für den Bearbeiter xxx:

Alles umfasst für libpng sind in pngconf.h. Wenn Sie sich ein Umfassen hinzufügen/ändern/löschen müssen, ist das der Platz, es zu tun. Das Umfassen, die draußen libpng nicht erforderlich sind, wird durch die PNG_INTERNAL Definition geschützt, die nur für jene Routinen innen libpng sich selbst definiert wird. Die Dateien in libpng richtig umfassen nur png.h, der pngconf.h umfasst.

Das Konfigurieren zlib:

Es gibt spezielle Funktionen, die Kompression zu konfigurieren. Vielleicht ändert der nützlichste das Kompressionsniveau, das zurzeit Eingangskompressionswerte in der Reihe 0 - 9 verwendet. Die Bibliothek verwendet normalerweise das Verzug-Kompressionsniveau (Z_DEFAULT_COMPRESSION = 6). Tests haben gezeigt, dass für eine große Mehrheit von Images Kompressionswerten in der Reihe 3-6 Kompresse fast sowie höhere Niveaus, und so viel schneller tut. Für On-Line-Anwendungen kann es wünschenswert sein, Höchstgeschwindigkeit (Z_BEST_SPEED = 1) zu haben. Mit Versionen von zlib danach v0.99 können Sie auch keine Kompression (Z_NO_COMPRESSION = 0) angeben, aber das würde Dateien schaffen, die größer sind als gerade Speicherung der rohen Bitmap. Sie können das Kompressionsniveau angeben, indem Sie rufen:

    png_set_compression_level(png_ptr, level);

Ein anderer nützlicher soll das von der Bibliothek verwendete Speicherniveau reduzieren. Der Speicherniveau-Verzug zu 8, aber kann es gesenkt werden, wenn Sie auf dem Speicher kurz sind (DOS zum Beispiel ausführend, wo Sie nur 640 Kilobyte haben). Bemerken Sie, dass das Speicherniveau wirklich eine Wirkung auf die Kompression hat; unter anderem werden niedrigere Ebenen auf Abteilungen von incompressible Daten hinauslaufen, die in kleineren gespeicherten Blöcken mit einem entsprechend größeren Verwandten oben bis zu 15 % im Grenzfall ausstrahlen werden.

   png_set_compression_mem_level(png_ptr, level);

Die anderen Funktionen sind, um zlib zu konfigurieren. Sie werden für den normalen Gebrauch nicht empfohlen und können schriftlich eine ungültige PNG Datei resultieren. Sieh zlib.h für weitere Informationen darüber, was diese bedeuten.

    png_set_compression_strategy(png_ptr,
        strategy);
    png_set_compression_window_bits(png_ptr,
        window_bits);
    png_set_compression_method(png_ptr, method);
    png_set_compression_buffer_size(png_ptr, size);

Das Steuern der Reihe-Entstörung

Wenn Sie kontrollieren wollen, ob Libpng-Gebrauch-Entstörung oder nicht, welche Filter verwendet werden, und wie er über die Auswahl von Reihe-Filtern geht, können Sie eine dieser Funktionen nennen. Die Auswahl und Konfiguration von Reihe-Filtern können einen bedeutenden Einfluss auf die Größe und Verschlüsselungsgeschwindigkeit und einen etwas kleineren Einfluss auf die Entzifferungsgeschwindigkeit eines Images haben. Entstörung wird standardmäßig für RGB und grayscale Images (mit und ohne Alpha), aber nicht für paletted Images noch für irgendwelche Images mit Bit-Tiefen weniger als 8 Bit/Pixel ermöglicht.

Der 'Methode'-Parameter setzt die durchscheinende Hauptmethode, die zurzeit 'nur 0' im PNG 1.2 Spezifizierung ist. Die 'Filter'-Parameter-Sätze, welcher Filter () falls etwa, für jeden scanline verwendet werden sollte. Mögliche Werte sind PNG_ALL_FILTERS und PNG_NO_FILTERS, um Entstörung und von beziehungsweise einzuschalten.

Einzelne Filtertypen sind PNG_FILTER_NONE, PNG_FILTER_SUB, PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, der bitwise ORed zusammen mit '|' sein kann, um einen oder mehr Filter anzugeben, um zu verwenden. Diese Filter werden ausführlicher in der PNG Spezifizierung beschrieben. Wenn Sie vorhaben, den Filtertyp während des Kurses zu ändern, das Image zu schreiben, sollten Sie mit dem Fahne-Satz für alle Filter starten, die Sie vorhaben zu verwenden, so dass libpng seine internen Strukturen passend für alle Filtertypen initialisieren kann. (Bemerken Sie, dass das bedeutet, dass die erste Reihe immer anpassungsfähig gefiltert werden muss, weil libpng zurzeit die Filterpuffer nicht alloziert, bis png_write_row () zum ersten Mal genannt wird.)

   filters = PNG_FILTER_NONE | PNG_FILTER_SUB
              PNG_FILTER_UP | PNG_FILTER_AVE |
              PNG_FILTER_PAETH | PNG_ALL_FILTERS;

    png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE,
       filters);
              The second parameter can also be
              PNG_INTRAPIXEL_DIFFERENCING if you are
              writing a PNG to be embedded in a MNG
              datastream.  This parameter must be the
              same as the value of filter_method used
              in png_set_IHDR().

Es ist auch möglich zu beeinflussen, wie libpng aus der Zahl von den verfügbaren Filtern wählt. Das wird in einem oder beiden von zwei Wegen getan - es erzählend, wie wichtig es denselben Filter für aufeinander folgende Reihen behalten soll, und es die rechenbetonten Verhältniskosten der Filter erzählend.

  double weights[3] = {1.5, 1.3, 1.1},
       costs[PNG_FILTER_VALUE_LAST] =
       {1.0, 1.3, 1.3, 1.5, 1.7};

    png_set_filter_heuristics(png_ptr,
       PNG_FILTER_HEURISTIC_WEIGHTED, 3,
       weights, costs);

Die Gewichte multiplizieren Faktoren, die zu libpng anzeigen, dass der Reihe-Filter dasselbe für aufeinander folgende Reihen sein sollte es sei denn, dass ein anderer Reihe-Filter dass oft besser ist als der vorherige Filter. Im obengenannten Beispiel, wenn die vorherigen 3 Filter U-BOOT, U-BOOT, NIEMAND waren, konnte der U-BOOT-Filter eine "Summe von absoluten Unterschieden" 1.5 x 1.3mal höher haben als andere Filter und noch gewählt werden, während NIEMAND durchscheint, konnte eine Summe 1.1mal höher haben als andere Filter und noch gewählt werden. Unangegebene Gewichte werden genommen, um 1.0 zu sein, und die angegebenen Gewichte sollten sich wahrscheinlich wie diejenigen oben neigen, um neue Filter über ältere Filter zu betonen.

Die Filterkosten geben für jeden Filtertyp zu betrachtende Verhältnisentzifferungskosten an, Reihe-Filter auswählend. Das bedeutet, dass Filter mit höheren Kosten mit geringerer Wahrscheinlichkeit über Filter mit niedrigeren Kosten gewählt werden, es sei denn, dass ihre "Summe von absoluten Unterschieden" dass viel kleiner ist. Die Kosten widerspiegeln die genauen rechenbetonten Geschwindigkeiten der verschiedenen Filter nicht notwendigerweise, da das die Endbildgröße übermäßig beeinflussen würde.

Bemerken Sie, dass die Anzahlen oben rein für dieses Beispiel erfunden wurden und nur gegeben werden, um zu helfen, den Funktionsgebrauch zu erklären. Wenig Prüfung ist getan worden, um optimale Werte entweder für die Kosten oder für die Gewichte zu finden.

Das Entfernen unerwünschten Objekt-Codes

Es gibt ein Bündel #define in pngconf.h, die kontrollieren, welch sich von libpng löst, werden kompiliert. Ganz definiert Ende in _SUPPORTED. Wenn Sie nie dabei sind, eine Fähigkeit zu verwenden, können Sie sich #define zu #undef vor dem Wiederkompilieren libpng ändern und sich Code und Datenraum speichern, oder Sie können abbiegen einzelne Fähigkeiten damit definiert, die mit PNG_NO_ beginnen.

Sie können auch das ganze Umgestalten und Hilfsklotz-Fähigkeiten von in Massen mit Bearbeiter-Direktiven drehen, die PNG_NO_READ [definieren oder] _TRANSFORMS, oder PNG_NO_READ [SCHREIBEN oder] _ANCILLARY_CHUNKS, oder alle vier zusammen mit Direktiven SCHREIBEN, um einige der Fähigkeiten anzumachen, die Sie wirklich wollen. Die PNG_NO_READ [oder SCHREIBEN] _TRANSFORMS Direktiven machen die Extratransformationen unbrauchbar, aber verlassen noch die Bibliothek völlig fähig zum Lesen und Schreiben PNG Dateien mit allen bekannten öffentlichen Klötzen Gebrauch des PNG_NO_READ [oder SCHREIBEN] _ANCILLARY_CHUNKS Direktive produziert eine Bibliothek, die des Lesens oder Schreibens von Hilfsklötzen unfähig ist. Wenn Sie die progressive Lesen-Fähigkeit nicht verwenden, können Sie abbiegen das mit PNG_NO_PROGRESSIVE_READ (verwechseln Sie das mit der sich VERFLECHTENDEN Fähigkeit nicht, die Sie noch haben werden).

Das ganze Lesen und das Schreiben spezifischen Codes sind in getrennten Dateien, so sollte der Binder nur die Dateien ergreifen, braucht es. Jedoch, wenn Sie sich überzeugen wollen, oder wenn Sie einen Standplatz allein Bibliothek bauen, fangen alle Lesen-Dateien mit pngr an, und alle Schreiben-Dateien fangen mit pngw an. Die Dateien, die keinen vergleichen (wie png.c, pngtrans.c, usw.) werden sowohl für das Lesen als auch für Schreiben verwendet, und müssen immer umfasst werden. Der progressive Leser ist in pngpread.c

Wenn Sie schaffen oder eine dynamisch verbundene Bibliothek verteilen (ein.so oder DLL Datei), sollten Sie entfernen oder keine Teile der Bibliothek unbrauchbar machen, weil das mit verschiedenen Versionen der Bibliothek verbundene Anwendungen veranlassen wird zu scheitern, wenn sie Funktionen nicht verfügbar in Ihrer Bibliothek nennen. Die Größe der Bibliothek selbst sollte nicht ein Problem sein, weil nur jene Abteilungen, die wirklich verwendet werden, in den Speicher geladen werden.

Frage um Fehlersuchprogramm-Ausdruck

Die Makrodefinition PNG_DEBUG kann verwendet werden, um um Beseitigen-Ausdruck zu bitten. Setzen Sie es auf einen Wert der ganzen Zahl in der Reihe 0 bis 3. Höhere Anzahlen laufen auf Erhöhung von Mengen hinaus, bei Information zu debuggen. Die Information wird zur "stderr" Datei gedruckt, es sei denn, dass ein anderer Dateiname in der PNG_DEBUG_FILE Makrodefinition angegeben wird.

Wenn PNG_DEBUG> 0, die folgenden Funktionen (Makros) verfügbar werden:

     png_debug(level, message)
   png_debug1(level, message, p1)
   png_debug2(level, message, p1, p2)

in dem "Niveau" im Vergleich zu PNG_DEBUG ist, um zu entscheiden, die Nachricht ob zu drucken, ist "Nachricht" die formatierte Schnur, die zu drucken ist, und p1 und p2 sind Parameter, die in der Schnur gemäß printf-artigen Formatierungsdirektiven eingebettet werden sollen. Zum Beispiel,

  png_debug1(2, "foo=%d\n", foo);

wird dazu dekomprimiert

    if(PNG_DEBUG > 2)
     fprintf(PNG_DEBUG_FILE, "foo=%d\n", foo);
 

Wenn PNG_DEBUG definiert wird, aber Null ist, werden die Makros nicht definiert, aber Sie können noch PNG_DEBUG verwenden, um Ihr eigenes Beseitigen zu kontrollieren:

   #ifdef PNG_DEBUG
       fprintf(stderr, ...
   #endif

Wenn PNG_DEBUG = 1, die Makros definiert werden, aber nur png_debug Behauptungen, die Niveau = 0 wird haben, gedruckt. Es gibt nicht irgendwelche solche Behauptungen in dieser Version von libpng, aber wenn Sie einige einfügen, werden sie gedruckt.

VI. Laufzeitoptimierung

Eine neue Eigenschaft in libpng 1.2.0 ist die Fähigkeit, zwischen normalen und optimierten Versionen von einigen Routinen dynamisch umzuschalten. Zurzeit werden diese auf drei rechenbetont intensive Aufgaben beschränkt, indem sie PNG Dateien lesen: Entzifferung von Reihe-Filtern, Erweiterung verflechtend, und das Kombinieren verflochtener oder durchsichtiger Reihe-Daten mit vorherigen Reihe-Daten. Zurzeit sind die optimierten Versionen nur für x86 (Intel, AMD, usw.) Plattformen mit dem MMX Support verfügbar, obwohl sich das in zukünftige Versionen ändern kann. (Zum Beispiel könnten die non-MMX Assembleroptimierungen für zlib ähnlich Laufzeit-selectable in zukünftigen Veröffentlichungen werden, in welchem Fall libpng erweitert werden konnte, um sie zu unterstützen. Wechselweise könnte die Kompilierungszeit-Wahl des Gleitkommas gegen Routinen der ganzen Zahl für die Gammakorrektur Laufzeit-selectable werden.)

Weil solche Optimierungen dazu neigen, sehr Plattform - und Bearbeiter-Abhängiger, sowohl darin zu sein, wie sie geschrieben werden als auch darin, wie sie leisten, ist der neue Laufzeitcode in libpng geschrieben worden, um Programmen zu erlauben, entweder spezifische Optimierungen oder alle diese Optimierungen zu fragen, zu ermöglichen, und unbrauchbar zu machen. Zum Beispiel, um alle möglichen Optimierungen zu ermöglichen (denkend, dass einige "Optimierungen" wirklich langsamer in seltenen Fällen laufen können):

    #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
       png_uint_32 mask, flags;

       flags = png_get_asm_flags(png_ptr);
       mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
       png_set_asm_flags(png_ptr, flags | mask);
    #endif

Um nur für das Lesen von PNGs wichtige Optimierungen zu ermöglichen, verwenden Sie PNG_SELECT_READ allein, indem Sie png_get_asm_flagmask () rufen; ähnlich, um nur das Schreiben zu optimieren. Alle Optimierungen unbrauchbar zu machen:

#if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
       flags = png_get_asm_flags(png_ptr);
       mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
       png_set_asm_flags(png_ptr, flags & ~mask);
    #endif

Um nur MMX-zusammenhängende Eigenschaften zu ermöglichen oder unbrauchbar zu machen, verwenden Sie png_get_mmx_flagmask () im Platz von png_get_asm_flagmask (). Die mmx Version nimmt einen zusätzlichen Parameter:

   #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
       int selection = PNG_SELECT_READ | PNG_SELECT_WRITE;
       int compilerID;

       mask = png_get_mmx_flagmask(selection, &compilerID);
    #endif

Auf der Rückkehr wird compilerID anzeigen, die welche Version der MMX Assembleroptimierungen kompiliert wurde. Zurzeit bestehen zwei Geschmäcke: Microsoft Visual C ++ (compilerID == 1) und GNU C (a.k.a. gcc/gas, compilerID == 2). Auf non-x86 Plattformen oder auf ohne MMX Optimierungen kompilierten Systemen wird ein Wert-1 verwendet.

Bemerken Sie, dass beide png_get_asm_flagmask () und png_get_mmx_flagmask () geben alle gültig, settable Optimierungsbit für die Version der Bibliothek zurück, es ist zurzeit im Gebrauch. Im Fall von geteilt (dynamisch verbunden) Bibliotheken kann das Optimierungen umfassen, die zurzeit nicht bestanden, wurde der Code geschrieben und kompiliert. Es ist auch natürlich möglich, nur bekannte, spezifische Optimierungen zu ermöglichen; zum Beispiel:

    #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
       flags = PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
             | PNG_ASM_FLAG_MMX_READ_INTERLACE    \
             | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
             | PNG_ASM_FLAG_MMX_READ_FILTER_UP    \
             | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
             | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
       png_set_asm_flags(png_ptr, flags);
    #endif

Diese Methode würde nur die MMX lesen-Optimierungen ermöglichen, die zur Zeit von libpng 1.2.0's Veröffentlichung, unabhängig davon verfügbar sind, ob eine spätere Version des DLL wirklich verwendet wurde. (Bemerken Sie auch, dass diese Funktionen in Versionen nicht bestanden, die älter sind als 1.2.0, so würde jeder Versuch, einen dynamisch verbundenen app auf solch einer älteren Version auszuführen, scheitern.)

Um ob die Prozessor-Supports MMX Instruktionen überhaupt zu bestimmen, verwenden Sie den png_mmx_support () Funktion:

    #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
       mmxsupport = png_mmx_support();
    #endif

Es kehrt-1 zurück, wenn MMX Support in libpng, 0 nicht kompiliert wird, wenn MMX-Code kompiliert wird, aber MMX wird durch den Prozessor, oder 1 nicht unterstützt, wenn MMX Support völlig verfügbar ist. Bemerken Sie, dass png_mmx_support (), png_get_mmx_flagmask (), und png_get_asm_flagmask () alle genannt werden können ohne zu allozieren und ini-tializing irgendwelche PNG Strukturen (zum Beispiel, als ein Teil eines Gebrauch-Bildschirms oder "über" den Kasten).

Der folgende Code kann verwendet werden, um eine Anwendung davon abzuhalten, die thread_Unsafe-Eigenschaften zu verwenden, selbst wenn libpng mit definiertem PNG_THREAD_UNSAFE_OK gebaut wurde:

#if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) \
  && defined(PNG_THREAD_UNSAFE_OK)
    /* Disable thread-unsafe features of pnggccrd */
    if (png_access_version() >= 10200)
    {
      png_uint_32 mmx_disable_mask = 0;
      png_uint_32 asm_flags;

      mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
                          | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
                          | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
                          | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
      asm_flags = png_get_asm_flags(png_ptr);
      png_set_asm_flags(png_ptr, asm_flags & ~mmx_disable_mask);
    }
#endif

Für umfassendere Beispiele des Laufzeitabfragens, ermöglichend und von optimierten Eigenschaften unfähig machend, sieh contrib/gregbook/readpng2.c im libpng Quellcode-Vertrieb.

VII. MNG Support

Die MNG Spezifizierung (verfügbar an http://www.libpng.org/pub/mng/) erlaubt bestimmte Erweiterungen auf PNG für PNG Images, die in MNG datastreams eingebettet werden. Libpng kann einige dieser Erweiterungen unterstützen. Um ihnen zu ermöglichen, verwenden Sie den png_permit_mng_features () Funktion:

  feature_set = png_permit_mng_features(png_ptr, mask)
   mask is a png_uint_32 containing the logical OR of the
        features you want to enable.  These include
        PNG_FLAG_MNG_EMPTY_PLTE
        PNG_FLAG_MNG_FILTER_64
        PNG_ALL_MNG_FEATURES
   feature_set is a png_32_uint that is the logical AND of
      your mask with the set of MNG features that is
      supported by the version of libpng that you are using.

Es ist ein Fehler, diese Funktion zu verwenden, lesend oder eine eigenständige PNG Datei mit der PNG 8-Byte-Unterschrift schreibend. Der PNG datastream muss in einem MNG datastream gewickelt werden. Als ein Minimum muss es die MNG 8-Byte-Unterschrift und den MHDR haben und Klötze AUSBESSERN. Libpng stellt Support für diese oder irgendwelche anderen MNG Klötze nicht zur Verfügung; Ihre Anwendung muss seinen eigenen Support für sie zur Verfügung stellen. Sie können denken mögen, libmng (verfügbar an http://www.libmng.com/) stattdessen zu verwenden.

VIII. Änderungen zu Libpng von der Version 0.88

Es sollte bemerkt werden, dass Versionen von libpng später als 0.96 vom ursprünglichen libpng Autor, Guy Schalnat, noch von Andreas Dilger nicht verteilt werden, der vom Kerl während 1996 und 1997 übernommen, und Versionen 0.89 bis 0.96, aber eher durch ein anderes Mitglied der ursprünglichen PNG Gruppe, Glenn Randers-Pehrson verteilt hatte. Kerl und Andreas sind noch lebendig und so, aber sie sind zu anderen Dingen weitergegangen.

Die alten Libpng-Funktionen png_read_init (), png_write_init (), png_info_init (), png_read_destroy (), und png_write_destroy () sind zu PNG_INTERNAL in der Version 0.95 bewegt worden, um ihren Gebrauch zu entmutigen. Diese Funktionen werden von der libpng Version 2.0.0 entfernt.

Die bevorzugte Methode, die libpng Strukturen zu schaffen und zu initialisieren, ist über den png_create_read_struct (), png_create_write_struct (), und png_create_info_struct (), weil sie die Größe der Strukturen von der Anwendung isolieren, Versionsfehlerkontrolle erlauben, und auch den Gebrauch von kundenspezifischen Fehlerbehandlungsroutinen während der Initialisierung erlauben, die die alten Funktionen nicht tun. Die Funktionen png_read_destroy () und png_write_destroy () befreien den Speicher nicht wirklich, dass libpng alloziert für diese structs, aber gerade die Datenstrukturen neu fassen, so können sie statt png_destroy_read_struct () und png_destroy_write_struct verwendet werden (), wenn Sie finden, dass es zu viel System gibt, das oben alloziert und den png_struct für jedes gelesene Image befreit.

Das Setzen der Fehlerrückrufaktionen über png_set_message_fn () vorher png_read_init () wurde als in libpng-0.88 angedeutet wird nicht mehr unterstützt, weil das Anwendungen verursachte, die kundenspezifische Fehlerfunktionen nicht verwenden, um zu scheitern, wenn der png_ptr zur Null nicht initialisiert wurde. Es ist noch möglich, die Fehlerrückrufaktionen DANACH png_read_init () zu setzen, oder sie mit png_set_error_fn zu ändern (), der im Wesentlichen dieselbe Funktion, aber mit einem neuen Namen ist, um Kompilationsfehler mit Anwendungen zu zwingen, die versuchen, die alte Methode zu verwenden.

Mit der Version 1.0.7 anfangend, können Sie herausfinden, welche Version der Bibliothek Sie an der Laufzeit verwenden:

    png_uint_32 libpng_vn = png_access_version_number();

Die Anzahl libpng_vn wird von der Hauptversion, geringen Version mit der führenden Null, und Freigabenummer mit der führenden Null gebaut, (z.B, libpng_vn für die Version 1.0.7 ist 10007).

Sie können auch überprüfen, welche Version von png.h Sie verwendeten, indem Sie Ihre Anwendung kompilierten:

  png_uint_32 application_vn = PNG_LIBPNG_VER;

IX. Y2K Compliance in libpng

Am 2. Oktober 2002

Da die PNG Entwicklungsgruppe ad hoc Körper ist, können wir nicht eine offizielle Behauptung machen.

Das ist Ihre inoffizielle Versicherung, dass libpng von der Version 0.71 und aufwärts bis 1.2.5 entgegenkommend Y2K sind. Es ist mein Glaube, dass frühere Versionen auch entgegenkommender Y2K waren.

Libpng hat nur dreijährige Felder. Man ist eine nicht unterzeichnete ganze 2-Byte-Zahl, die Jahre bis zu 65535 halten wird. Die anderen zwei halten das Datum im Textformat, und werden Jahre bis zu 9999 halten.

Die ganze Zahl ist

    "png_uint_16 year" in png_time_struct.

Die Schnuren sind

    "png_charp time_buffer" in png_struct and
    "near_time_buffer", which is a local character string in png.c.

Es gibt sieben Zeit-zusammenhängende Funktionen:

     png_convert_to_rfc_1123() in png.c
      (formerly png_convert_to_rfc_1152() in error)
    png_convert_from_struct_tm() in pngwrite.c, called
      in pngwrite.c
    png_convert_from_time_t() in pngwrite.c
    png_get_tIME() in pngget.c
    png_handle_tIME() in pngrutil.c, called in pngread.c
    png_set_tIME() in pngset.c
    png_write_tIME() in pngwutil.c, called in pngwrite.c

Alle scheinen, Daten richtig in einer Y2K Umgebung zu behandeln. Der png_convert_from_time_t () Funktionsaufrufe gmtime (), um sich vom System umzuwandeln, zeigen Zeit, die zurückkehrt (Jahr - 1900), den wir richtig zum vollen 4-stelligen Jahr umwandeln. Es gibt eine Möglichkeit, dass Anwendungen, libpng verwendend, 4-stellige Jahre in den png_convert_to_rfc_1123 () Funktion nicht passieren, oder dass sie nur ein 2-stellige Jahr statt des "Jahres - 1900" in den png_convert_from_struct_tm () Funktion falsch passieren, aber das ist nicht unter unserer Kontrolle. Die libpng Dokumentation hat immer festgestellt, dass sie mit 4-stelligen Jahren arbeitet, und die APIs als solcher dokumentiert worden sind.

Der Zeitklotz selbst ist auch entgegenkommender Y2K. Es verwendet eine nicht unterzeichnete ganze 2-Byte-Zahl, um das Jahr zu halten, und kann Jahre ebenso groß halten wie 65535.

zlib, auf den libpng abhängt, ist auch entgegenkommender Y2K. Es enthält keinen Datum-zusammenhängenden Code.

Glenn Randers-Pehrson
libpng maintainer
PNG Entwicklungsgruppe

X. Urheberrechtsvermerk, Disclaimer und Lizenz

Diese Kopie der Libpng-Benachrichtigungen wird für Ihre Bequemlichkeit zur Verfügung gestellt. Im Falle jeder Diskrepanz zwischen dieser Kopie und den Benachrichtigungen in der Datei png.h, der in den libpng Vertrieb umfasst wird, sollen die Letzteren vorherrschen.

COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:

If you modify libpng you may insert additional notices immediately following
this sentence.

libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are
Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
distributed according to the same disclaimer and license as libpng-1.0.6
with the following individuals added to the list of Contributing Authors

   Simon-Pierre Cadieux
   Eric S. Raymond
   Gilles Vollant

and with the following additions to the disclaimer:

   There is no warranty against interference with your enjoyment of the
   library or against infringement.  There is no warranty that our
   efforts or the library will fulfill any of your particular purposes
   or needs.  This library is provided with all faults, and the entire
   risk of satisfactory quality, performance, accuracy, and effort is with
   the user.

libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson
Distributed according to the same disclaimer and license as libpng-0.96,
with the following individuals added to the list of Contributing Authors:

   Tom Lane
   Glenn Randers-Pehrson
   Willem van Schaik

libpng versions 0.89, June 1996, through 0.96, May 1997, are
Copyright (c) 1996, 1997 Andreas Dilger
Distributed according to the same disclaimer and license as libpng-0.88,
with the following individuals added to the list of Contributing Authors:

   John Bowler
   Kevin Bracey
   Sam Bushell
   Magnus Holmgren
   Greg Roelofs
   Tom Tanner

libpng versions 0.5, May 1995, through 0.88, January 1996, are
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.

For the purposes of this copyright and license, "Contributing Authors"
is defined as the following set of individuals:

   Andreas Dilger
   Dave Martindale
   Guy Eric Schalnat
   Paul Schmidt
   Tim Wegner

The PNG Reference Library is supplied "AS IS".  The Contributing Authors
and Group 42, Inc. disclaim all warranties, expressed or implied,
including, without limitation, the warranties of merchantability and of
fitness for any purpose.  The Contributing Authors and Group 42, Inc.
assume no liability for direct, indirect, incidental, special, exemplary,
or consequential damages, which may result from the use of the PNG
Reference Library, even if advised of the possibility of such damage.

Permission is hereby granted to use, copy, modify, and distribute this
source code, or portions hereof, for any purpose, without fee, subject
to the following restrictions:

1. The origin of this source code must not be misrepresented.

2. Altered versions must be plainly marked as such and
   must not be misrepresented as being the original source.

3. This Copyright notice may not be removed or altered from
   any source or altered source distribution.

The Contributing Authors and Group 42, Inc. specifically permit, without
fee, and encourage the use of this source code as a component to
supporting the PNG file format in commercial products.  If you use this
source code in a product, acknowledgment is not required but would be
appreciated.


A "png_get_copyright" function is available, for convenient use in "about"
boxes and the like:

   printf("%s",png_get_copyright(NULL));

Also, the PNG logo (in PNG format, of course) is supplied in the
files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).

Libpng is OSI Certified Open Source Software.  OSI Certified Open Source
is a certification mark of the Open Source Initiative.

Glenn Randers-Pehrson

glennrp@users.sf.net
October 3, 2002

 
Suche
Aktuelle News

Der Nachfolger von Microsofts erstem Multimedia Player Zune steht ab dem 15. September zum Verkauf bereit und kann außerdem bereits vorbestellt werden

Auf einer Pressekonferenz in Japan hat Intel die angestrebten kommenden Technologie-Entwicklungen präsentiert. Bisher hält Intel an dem Tick-Tock-Prin

Nachdem sich ASUS in letzter Zeit recht erfolgreich auf dem Soundkarten Markt etabliert hat macht man sich nun daran auch Geräte zu entwickeln, die de

Netbooks sind schon seit einer Weile der Renner. Sie sind klein, leicht und haben oftmals sogar durch UMTS so gut wie überall einen Zugang zum WWW. Al

Der 10. September rückt immer näher und damit auch das Launch Datum der neuen Grafikkarten Generation von ATi. Wie bisher bei allen Karten gibt es dab

Um bei der Flut an Mainboards für Intels neuen Sockel 1156 nicht den Blick für andere interessante Dinge zu verlieren wollen wir an dieser Stelle das

Intels neue Lynnfield Prozessoren erreichen mittlerweile die ersten Shops und so ziehen natürlich auch die Mainboard Hersteller nach und werfen P55-Bo

Wie bereits in dem anderen Artikel gesagt gibt es die HD 4770-Serie seit nunmehr 4 Monaten und dennoch existieren bis auf eine Ausnahme von ASUS nur G

 


Sitemap