From 5a422aba704c375a307a902bafe658342e209906 Mon Sep 17 00:00:00 2001 From: scuri Date: Fri, 17 Oct 2008 06:10:15 +0000 Subject: First commit - moving from LuaForge to SourceForge --- html/en/storage_guide.html | 311 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 311 insertions(+) create mode 100644 html/en/storage_guide.html (limited to 'html/en/storage_guide.html') diff --git a/html/en/storage_guide.html b/html/en/storage_guide.html new file mode 100644 index 0000000..e225ae5 --- /dev/null +++ b/html/en/storage_guide.html @@ -0,0 +1,311 @@ + + + + + + +Storage Guide + + + + + +

Storage Guide

+

Reading

+ +

When reading the file extension is not relevant to determine the file + format, but it is used to speed up the process of finding the correct format. + With few exceptions the format drivers that access multiple images can read + them in any sequence you want.

+

During the read process the original data can be converted to some options + of user data. Not all conversions are available. You can convert any data to a + bitmap version of it, and you can select any of the color mode flags + IM_ALPHA, IM_PACKED and IM_TOPDOWN, + regardless of the file original configuration.

+

Remember that even if all the images in the file have the same parameters + you still have to call imFileReadImageInfo before calling imFileReadImageData.

+

In the following example all the images in the file are loaded.

+ +
char format[10], compression[10];
+int error, image_count;
+int width, height, color_mode, data_type;
+void* data;
+
+imFile* ifile = imFileOpen("test.tif", &error);
+if (error != IM_ERR_NONE) 
+  // handle the error
+
+imFileGetInfo(ifile, format, compression, &image_count);
+
+for (i = 0; i < image_count, i++)
+{
+  error = imFileReadImageInfo(ifile, i, &width, &height, &color_mode, &data_type);
+  if (error != IM_ERR_NONE) 
+    // handle the error
+
+  // prepare data
+
+  error = imFileReadImageData(ifile, data, 0, -1); // no bitmap convertion, use original color mode flags
+  if (error != IM_ERR_NONE) 
+    // handle the error
+
+  // store data somewhere
+}
+
+imFileClose(ifile); 
+ +

A more simple code loads only the first image in the file:

+ +
imFile* ifile = imFileOpen(file_name, &error);
+
+imFileReadImageInfo(ifile, 0, &width, &height, &color_mode, &data_type);
+
+imFileReadImageData(ifile, data, 0, -1);
+
+imFileClose(ifile); 
+ +

If you are using the imImage structure it is easier:

+ +
imFile* ifile = imFileOpen(file_name, &error);
+ 
+imImage* image = imFileLoadImage(ifile, 0, &error);
+
// or use imFileLoadBitmap to force a bitmap conversion
+
+imFileClose(ifile);
+ +

Or the simplest version:

+ +
imImage* image = imFileImageLoad(file_name, 0, &error);
+ + +

Writing

+ +

When writing there is no color space or data type conversion. Only color + mode flags can be different: IM_ALPHA, IM_PACKED and + IM_TOPDOWN. You just have to describe your data and the imFileWriteImageData will handle the color mode flag differences.

+

Of course you still have to check the error codes because, not all color + spaces and data types are supported by each format.

+

When saving a sequence of images you must provide each image in the order + that they will be in the file. For a video or animation start from frame 0 and + go on, you can not jump or change the frame order. Also when saving videos you + should not forget to save the numbers of frames per second in the attribute + "FPS", the default value is 15.

+

For all the formats it is not necessary to set the compression, each driver + will choose a default compression. But you may set it using the function imFileSetInfo.

+

To save several images to the same file:

+ +
int error, width, height;
+void *data;
+
+imFile* ifile = imFileNew("test.tif", "TIFF", &error);
+if (error != IM_ERR_NONE) 
+  // handle the error
+
+for (i = 0; i < image_count, i++)
+{
+  error = imFileWriteImageInfo(ifile, width, height, IM_RGB, IM_BYTE);
+  if (error != IM_ERR_NONE) 
+    // handle the error
+
+  error = imFileWriteImageData(ifile, data);
+  if (error != IM_ERR_NONE) 
+    // handle the error
+}
+
+imFileClose(ifile); 
+ +

But remember that not all file formats supports several images. To save + just one image is more simple:

+ +
imFile* ifile = imFileNew(file_name, format, &error);
+
+error = imFileWriteImageInfo(ifile, width, height, color_mode, data_type);
+
+error = imFileWriteImageData(ifile, data);
+
+imFileClose(ifile); 
+ +

If you are using the imImage structure it is easier:

+ +
imFile* ifile = imFileNew(file_name, format, &error);
+
+error = imFileSaveImage(ifile, image);
+
+imFileClose(ifile);
+ +

Or the simplest version:

+ +
error = imFileImageSave(file_name, format, image);
+ + +

Error Messages

+ +

Here is a sample error message display using IUP and IM error codes:

+ +
static void imIupErrorMessage(int error, int interactive)
+{
+  char* lang = IupGetLanguage();
+  char *msg, *title;
+  if (strcmp(lang, "ENGLISH")==0)
+  {
+    title = "Error";
+    switch (error)
+    {
+    case IM_ERR_OPEN:
+      msg = "Error Opening File.";
+      break;
+    case IM_ERR_MEM:
+      msg = "Insuficient memory.";
+      break;
+    case IM_ERR_ACCESS:
+      msg = "Error Accessing File.";
+      break;
+    case IM_ERR_DATA:
+      msg = "Image type not Suported.";
+      break;
+    case IM_ERR_FORMAT:
+      msg = "Invalid Format.";
+      break;
+    case IM_ERR_COMPRESS:
+      msg = "Invalid or unsupported compression.";
+      break;
+    default:
+      msg = "Unknown Error.";
+    }
+  }
+  else
+  {
+    title = "Erro";
+    switch (error)
+    {
+    case IM_ERR_OPEN:
+      msg = "Erro Abrindo Arquivo.";
+      break;
+    case IM_ERR_MEM:
+      msg = "Memória Insuficiente.";
+      break;
+    case IM_ERR_ACCESS:
+      msg = "Erro Acessando Arquivo.";
+      break;
+    case IM_ERR_DATA:
+      msg = "Tipo de Imagem não Suportado.";
+      break;
+    case IM_ERR_FORMAT:
+      msg = "Formato Inválido.";
+      break;
+    case IM_ERR_COMPRESS:
+      msg = "Compressão Inválida ou não Suportada.";
+      break;
+    default:
+      msg = "Erro Desconhecido.";
+    }
+  }
+
+  if (interactive)
+    IupMessage(title, msg);
+  else
+    printf("%s: %s", title, msg);
+}
+
+ + +

About File Formats

+ +

TIFF is still the most complete format available. It could be better if + Adobe releases the revision 7, but it is on stand by. TIFF supports all the IM + image representation concepts. In fact we were partially inspired by the TIFF + specification. My suggestion is whenever possible use TIFF.

+

But TIFF may not be the ideal format for many situations. The W3C standards + include only JPEG, GIF and PNG for Web browsers. JPEG forces the image to be + RGB or Gray with a lossy compressed. GIF forces the image to be MAP with LZW + compression. PNG forces the image to be RGB, MAP, Gray or Binary, with Deflate + compression. So these characteristics are necessary to force small values for + faster downloads.

+

JPEG is to be used for photographic content, PNG should be used for the + remaining cases, but GIF is still the best to do simple animated images.

+

Except for some specific cases where a format is needed for compatibility, + the other formats are less important. TGA, PCX, RAS, SGI and BMP have almost + the same utility.

+

JP2 must be used for JPEG-2000 compression, would be nice if a new TIFF + specification includes this standard.

+

Since PNM has a textual header it is very simple to teach for students so + they can actually "see" the header. It is also a format easy to share images, + but it does not do much more than that.

+

The TIFF and the GIF format also have support for multiple images. This + does not necessarily defines an animation, pyramid nor a volume, but some + times they are used in these ways.

+

GIF became very popular to build animations for the Web, and since the LZW + patent expired Unisys realized that charging the usage isn't going to work and + so they did not renew it. LZW is fully supported at IM.

+

IM also supports video formats like AVI and WMV as external libraries. In + these cases the frames are also loaded as a sequence of individual images. + Sound is not supported.

+

TIFF, JPEG and PNG have an extensive list of attributes, most of them are + listed in the documentation, but some custom attributes may come up when + reading an image from file.

+ +

New File Formats

+ +

Again the easiest way is to look at the source code of an already + implemented format. The RAS, BMP, TGA and SGI formats are very simple to + follow.

+

Basically you have to implement a class that inherits from imFormat + and implement its virtual methods. You can use the imBinFile functions + for I/O or use an external SDK.

+

For more information see + File + Format SDK.

+ +

Memory I/O and Others

+ +

For the majority of the formats, with the exception of the ones that use + external SDKs, the I/O is done by the imBinFile module.

+

This module can be configured to access other types of media by + implementing a driver. There are some predefined drivers see + Reference + / Utilities / Binary File Access.

+

One very useful is the Memory Buffer where you can read and write a + file in memory. The activation is very simple, it needs to happen just before + the imFileOpen/imFileNew functions. But the file name must be a + pointer to an imBinMemoryFileName structure instead of a string. + Se the example bellow:

+ +
int old_mode = imBinFileSetCurrentModule(IM_MEMFILE);
+
+imBinMemoryFileName MemFileName; // This structure must exists 
+    while the file remains open.
+ MemFileName.buffer = NULL; // Let the library initializes the buffer,
+                           + // but it must be freed the the application, free(MemFileName.buffer) + MemFileName.size = 1024; // The initial size
+ MemFileName.reallocate = 1.5; // The reallocation will increase 50% the + buffer.
+                              + // This is used only when writing with a variable buffer.
+                              + // Use 0 to fix the buffer size. + +int error;
+ imFile* ifile = imFileNew((const char*)&MemFileName, "GIF", &error); + +imBinFileSetCurrentModule(old_mode); // The mode needs to be active + only for the imFileOpen/imFileNew call. + +if (error != IM_ERR_NONE) ....
+ +

Another driver interesting is the Subfile where you can read and + write from a file that is already open. This is very important for formats + that can have an embedded format inside. In this module the file_name + is a pointer to an imBinFile  + structure from any other module that uses the imBinFile functions. The + imBinFileSize will return the full file size, but the imBinFileSeekTo and + imBinFileTell functions will + compensate the position when the subfile was open.

+

Using imBinFileSetCurrentModule(IM_SUBFILE) just like the example above will + allow you to open a subfile using the imFileOpen/imFileNew + functions.

+ + + + + -- cgit v1.2.3