Example #1
0
ImageInput *
ImageInput::open (const std::string &filename,
                  const ImageSpec *config)
{
    if (config == NULL) {
        // Without config, this is really just a call to create-with-open.
        return ImageInput::create (filename, true, std::string());
    }

    // With config, create without open, then try to open with config.
    ImageInput *in = ImageInput::create (filename, false, std::string());
    if (! in)
        return NULL;  // create() failed
    ImageSpec newspec;
    if (in->open (filename, newspec, *config))
        return in;   // creted fine, opened fine, return it

    // The open failed.  Transfer the error from 'in' to the global OIIO
    // error, delete the ImageInput we allocated, and return NULL.
    std::string err = in->geterror();
    if (err.size())
        pvt::error ("%s", err.c_str());
    delete in;
    return NULL;
}
Example #2
0
static bool is_float_image(const string& filename)
{
	ImageInput *in = ImageInput::create(filename);
	bool is_float = false;

	if(in) {
		ImageSpec spec;

		if(in->open(filename, spec)) {
			/* check the main format, and channel formats;
			 * if any take up more than one byte, we'll need a float texture slot */
			if(spec.format.basesize() > 1)
				is_float = true;

			for(size_t channel = 0; channel < spec.channelformats.size(); channel++) {
				if(spec.channelformats[channel].basesize() > 1)
					is_float = true;
			}

			in->close();
		}

		delete in;
	}

	return is_float;
}
Example #3
0
void lux::readOIIOImage( const char* fname, Image& img  )
{
   int xres, yres, channels;
   ImageInput *in = ImageInput::create (fname);
   if (! in) {return;}
   ImageSpec spec;
   in->open (fname, spec);
   xres = spec.width;
   yres = spec.height;
   channels = spec.nchannels;
   float* pixels = new float[xres*yres*channels];
   in->read_image (TypeDesc::FLOAT, pixels);

   img.reset( xres, yres, channels );
   long index = 0;
   for( int j=0;j<yres;j++)
   {
      for( int i=0;i<xres;i++ )
      {
         for( int c=0;c<channels;c++ )
         {
	    img.value(i,img.Height() - j - 1,c) = pixels[index++];
         }
      }
   }
   in->close ();
   delete in;
   delete[] pixels;
}
void
RawInput::read_tiff_metadata (const std::string &filename)
{
    // Many of these raw formats look just like TIFF files, and we can use
    // that to extract a bunch of extra Exif metadata and thumbnail.
    ImageInput *in = ImageInput::create ("tiff");
    if (! in) {
        (void) OIIO::geterror();  // eat the error
        return;
    }
    ImageSpec newspec;
    bool ok = in->open (filename, newspec);
    if (ok) {
        // Transfer "Exif:" metadata to the raw spec.
        for (ParamValueList::const_iterator p = newspec.extra_attribs.begin();
                p != newspec.extra_attribs.end();  ++p) {
            if (Strutil::istarts_with (p->name().c_str(), "Exif:")) {
                m_spec.attribute (p->name().c_str(), p->type(), p->data());
            }
        }
    }

    in->close ();
    delete in;
}
Example #5
0
static bool is_float_image(const string& filename)
{
	ImageInput *in = ImageInput::create(filename);
	bool is_float = false;

	if(in) {
		ImageSpec spec;

		if(in->open(filename, spec)) {
			/* check the main format, and channel formats;
			   if any are non-integer, we'll need a float texture slot */
			if(spec.format == TypeDesc::HALF ||
			   spec.format == TypeDesc::FLOAT ||
			   spec.format == TypeDesc::DOUBLE) {
				is_float = true;
			}

			for(size_t channel = 0; channel < spec.channelformats.size(); channel++) {
				if(spec.channelformats[channel] == TypeDesc::HALF ||
				   spec.channelformats[channel] == TypeDesc::FLOAT ||
				   spec.channelformats[channel] == TypeDesc::DOUBLE) {
					is_float = true;
				}
			}

			in->close();
		}

		delete in;
	}

	return is_float;
}
void readOIIOImage( const char* fname, float* img  )
{
  int xres, yres, channels;
  ImageInput *in = ImageInput::create (fname);
  if (! in) {return;}
  ImageSpec spec;
  in->open (fname, spec);
  xres = spec.width;
  yres = spec.height;
  channels = spec.nchannels;
  float* pixels = new float[xres*yres*channels];

  in->read_image (TypeDesc::FLOAT, pixels);
  long index = 0;
  for( int j=0;j<yres;j++)
  {
    for( int i=0;i<xres;i++ )
    {
      for( int c=0;c<channels;c++ )
      {
        img[ (i + xres*(yres - j - 1))*channels + c ] = pixels[index++];
      }
    }
  }

  in->close ();
  delete in;
}
Example #7
0
void lux::readOIIOImage( const char* fname, Image& img, map<string,string>& labels )
{
   int xres, yres, channels;
   ImageInput *in = ImageInput::create (fname);
   if (! in) {return;}
   ImageSpec spec;
   in->open (fname, spec);
   xres = spec.width;
   yres = spec.height;
   channels = spec.nchannels;
   float* pixels = new float[xres*yres*channels];
   in->read_image (TypeDesc::FLOAT, pixels);

   img.reset( xres, yres, channels );
   long index = 0;
   for( int j=0;j<yres;j++)
   {
      for( int i=0;i<xres;i++ )
      {
         for( int c=0;c<channels;c++ )
         {
	    img.value(i,img.Height() - j - 1,c) = pixels[index++];
         }
      }
   }

   for( size_t i=0;i<spec.extra_attribs.size();i++)
   {
      const ParamValue& p = spec.extra_attribs[i];
      string name = p.name().c_str();
      string value = spec.metadata_val ( p, true);
      labels[name] = value;
   }

   in->close ();
   delete in;
   delete[] pixels;
}
Example #8
0
ImageInput *
ImageInput::create (const std::string &filename, 
                    bool do_open,
                    const std::string &plugin_searchpath)
{
    if (filename.empty()) { // Can't even guess if no filename given
        pvt::error ("ImageInput::create() called with no filename");
        return NULL;
    }

    // Extract the file extension from the filename (without the leading dot)
    std::string format = Filesystem::extension (filename, false);
    if (format.empty()) {
        // If the file had no extension, maybe it was itself the format name
        format = filename;
    }

    ImageInput::Creator create_function = NULL;
    { // scope the lock:
        recursive_lock_guard lock (imageio_mutex);  // Ensure thread safety

        // See if it's already in the table.  If not, scan all plugins we can
        // find to populate the table.
        Strutil::to_lower (format);
        InputPluginMap::const_iterator found = input_formats.find (format);
        if (found == input_formats.end()) {
            catalog_all_plugins (plugin_searchpath.size() ? plugin_searchpath
                                 : pvt::plugin_searchpath.string());
            found = input_formats.find (format);
        }
        if (found != input_formats.end())
            create_function = found->second;
    }

    // Remember which prototypes we've already tried, so we don't double dip.
    std::vector<ImageInput::Creator> formats_tried;

    std::string specific_error;
    if (create_function) {
        if (filename != format) {
            // If given a full filename, double-check that our guess
            // based on the extension actually works.  You never know
            // when somebody will have an incorrectly-named file, let's
            // deal with it robustly.
            formats_tried.push_back (create_function);
            ImageInput *in = (ImageInput *)create_function();
            if (! do_open && in && in->valid_file(filename)) {
                // Special case: we don't need to return the file
                // already opened, and this ImageInput says that the
                // file is the right type.
                return in;
            }
            ImageSpec tmpspec;
            bool ok = in && in->open (filename, tmpspec);
            if (ok) {
                // It worked
                if (! do_open)
                    in->close ();
                return in;
            } else {
                // Oops, it failed.  Apparently, this file can't be
                // opened with this II.  Clear create_function to force
                // the code below to check every plugin we know.
                create_function = NULL;
                if (in)
                    specific_error = in->geterror();
            }
            delete in;
        }
    }

    if (! create_function) {
        // If a plugin can't be found that was explicitly designated for
        // this extension, then just try every one we find and see if
        // any will open the file.  Pass it a configuration request that
        // includes a "nowait" option so that it returns immediately if
        // it's a plugin that might wait for an event, like a socket that
        // doesn't yet exist).
        ImageSpec config;
        config.attribute ("nowait", (int)1);
        recursive_lock_guard lock (imageio_mutex);  // Ensure thread safety
        for (InputPluginMap::const_iterator plugin = input_formats.begin();
             plugin != input_formats.end(); ++plugin)
        {
            // If we already tried this create function, don't do it again
            if (std::find (formats_tried.begin(), formats_tried.end(),
                           plugin->second) != formats_tried.end())
                continue;
            formats_tried.push_back (plugin->second);  // remember

            ImageSpec tmpspec;
            ImageInput *in = NULL;
            try {
                in = plugin->second();
            } catch (...) {
                // Safety in case the ctr throws an exception
            }
            if (! in)
                continue;
            if (! do_open && ! in->valid_file(filename)) {
                // Since we didn't need to open it, we just checked whether
                // it was a valid file, and it's not.  Try the next one.
                delete in;
                continue;
            }
            // We either need to open it, or we already know it appears
            // to be a file of the right type.
            bool ok = in->open(filename, tmpspec, config);
            if (ok) {
                if (! do_open)
                    in->close ();
                return in;
            }
            delete in;
        }
    }

    if (create_function == NULL) {
        recursive_lock_guard lock (imageio_mutex);  // Ensure thread safety
        if (input_formats.empty()) {
            // This error is so fundamental, we echo it to stderr in
            // case the app is too dumb to do so.
            const char *msg = "ImageInput::create() could not find any ImageInput plugins!\n"
                          "    Perhaps you need to set OIIO_LIBRARY_PATH.\n";
            fprintf (stderr, "%s", msg);
            pvt::error ("%s", msg);
        }
        else if (! specific_error.empty()) {
            // Pass along any specific error message we got from our
            // best guess of the format.
            pvt::error ("%s", specific_error);
        }
        else if (Filesystem::exists (filename))
            pvt::error ("OpenImageIO could not find a format reader for \"%s\". "
                        "Is it a file format that OpenImageIO doesn't know about?\n",
                         filename.c_str());
        else
            pvt::error ("Image \"%s\" does not exist. Also, it is not the name of an image format that OpenImageIO recognizes.\n",
                         filename.c_str());
        return NULL;
    }

    return (ImageInput *) create_function();
}
Example #9
0
bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_img)
{
	if(img->filename == "")
		return false;

	/* load image from file through OIIO */
	ImageInput *in = ImageInput::create(img->filename);

	if(!in)
		return false;

	ImageSpec spec;

	if(!in->open(img->filename, spec)) {
		delete in;
		return false;
	}

	/* we only handle certain number of components */
	int width = spec.width;
	int height = spec.height;
	int components = spec.nchannels;

	if(!(components == 1 || components == 3 || components == 4)) {
		in->close();
		delete in;
		return false;
	}

	printf("loading float image: '%s' %dx%d\n", img->filename.c_str(), width, height);

	/* read RGBA pixels */
	float *pixels = (float*)tex_img.resize(width, height);
	int scanlinesize = width*components*sizeof(float);

	in->read_image(TypeDesc::FLOAT,
		(uchar*)pixels + (height-1)*scanlinesize,
		AutoStride,
		-scanlinesize,
		AutoStride);

	in->close();
	delete in;

	if(components == 3) {
		for(int i = width*height-1; i >= 0; i--) {
			pixels[i*4+3] = 1.0f;
			pixels[i*4+2] = pixels[i*3+2];
			pixels[i*4+1] = pixels[i*3+1];
			pixels[i*4+0] = pixels[i*3+0];
		}
	}
	else if(components == 1) {
		for(int i = width*height-1; i >= 0; i--) {
			pixels[i*4+3] = 1.0f;
			pixels[i*4+2] = pixels[i];
			pixels[i*4+1] = pixels[i];
			pixels[i*4+0] = pixels[i];
		}
	}

	return true;
}
Example #10
0
bool ImageManager::get_image_metadata(const string& filename,
                                      void *builtin_data,
                                      ImageMetaData& metadata)
{
	memset(&metadata, 0, sizeof(metadata));

	if(builtin_data) {
		if(builtin_image_info_cb) {
			builtin_image_info_cb(filename, builtin_data, metadata);
		}
		else {
			return false;
		}

		if(metadata.is_float) {
			metadata.is_linear = true;
			metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT;
		}
		else {
			metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE;
		}

		return true;
	}

	/* Perform preliminary checks, with meaningful logging. */
	if(!path_exists(filename)) {
		VLOG(1) << "File '" << filename << "' does not exist.";
		return false;
	}
	if(path_is_directory(filename)) {
		VLOG(1) << "File '" << filename << "' is a directory, can't use as image.";
		return false;
	}

	ImageInput *in = ImageInput::create(filename);

	if(!in) {
		return false;
	}

	ImageSpec spec;
	if(!in->open(filename, spec)) {
		delete in;
		return false;
	}

	metadata.width = spec.width;
	metadata.height = spec.height;
	metadata.depth = spec.depth;

	/* check the main format, and channel formats;
	 * if any take up more than one byte, we'll need a float texture slot */
	if(spec.format.basesize() > 1) {
		metadata.is_float = true;
		metadata.is_linear = true;
	}

	for(size_t channel = 0; channel < spec.channelformats.size(); channel++) {
		if(spec.channelformats[channel].basesize() > 1) {
			metadata.is_float = true;
			metadata.is_linear = true;
		}
	}

	/* check if it's half float */
	if(spec.format == TypeDesc::HALF)
		metadata.is_half = true;

	/* basic color space detection, not great but better than nothing
	 * before we do OpenColorIO integration */
	if(metadata.is_float) {
		string colorspace = spec.get_string_attribute("oiio:ColorSpace");

		metadata.is_linear = !(colorspace == "sRGB" ||
							   colorspace == "GammaCorrected" ||
							   (colorspace == "" &&
								   (strcmp(in->format_name(), "png") == 0 ||
									strcmp(in->format_name(), "tiff") == 0 ||
									strcmp(in->format_name(), "dpx") == 0 ||
									strcmp(in->format_name(), "jpeg2000") == 0)));
	}
	else {
		metadata.is_linear = false;
	}

	/* set type and channels */
	metadata.channels = spec.nchannels;

	if(metadata.is_half) {
		metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_HALF4 : IMAGE_DATA_TYPE_HALF;
	}
	else if(metadata.is_float) {
		metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT;
	}
	else {
		metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE;
	}

	in->close();
	delete in;

	return true;
}
Example #11
0
ImageManager::ImageDataType ImageManager::get_image_metadata(const string& filename,
                                                             void *builtin_data,
                                                             bool& is_linear)
{
	bool is_float = false, is_half = false;
	is_linear = false;
	int channels = 4;

	if(builtin_data) {
		if(builtin_image_info_cb) {
			int width, height, depth;
			builtin_image_info_cb(filename, builtin_data, is_float, width, height, depth, channels);
		}

		if(is_float) {
			is_linear = true;
			return (channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT;
		}
		else {
			return (channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE;
		}
	}

	ImageInput *in = ImageInput::create(filename);

	if(in) {
		ImageSpec spec;

		if(in->open(filename, spec)) {
			/* check the main format, and channel formats;
			 * if any take up more than one byte, we'll need a float texture slot */
			if(spec.format.basesize() > 1) {
				is_float = true;
				is_linear = true;
			}

			for(size_t channel = 0; channel < spec.channelformats.size(); channel++) {
				if(spec.channelformats[channel].basesize() > 1) {
					is_float = true;
					is_linear = true;
				}
			}

			/* check if it's half float */
			if(spec.format == TypeDesc::HALF)
				is_half = true;

			channels = spec.nchannels;

			/* basic color space detection, not great but better than nothing
			 * before we do OpenColorIO integration */
			if(is_float) {
				string colorspace = spec.get_string_attribute("oiio:ColorSpace");

				is_linear = !(colorspace == "sRGB" ||
				              colorspace == "GammaCorrected" ||
				              (colorspace == "" &&
				                  (strcmp(in->format_name(), "png") == 0 ||
				                   strcmp(in->format_name(), "tiff") == 0 ||
				                   strcmp(in->format_name(), "dpx") == 0 ||
				                   strcmp(in->format_name(), "jpeg2000") == 0)));
			}
			else {
				is_linear = false;
			}

			in->close();
		}

		delete in;
	}

	if(is_half) {
		return (channels > 1) ? IMAGE_DATA_TYPE_HALF4 : IMAGE_DATA_TYPE_HALF;
	}
	else if(is_float) {
		return (channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT;
	}
	else {
		return (channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE;
	}
}
Example #12
0
struct ImBuf *imb_load_photoshop(const char *filename, int flags, char colorspace[IM_MAX_SPACE])
{
	ImageInput *in = NULL;
	struct ImBuf *ibuf = NULL;
	int width, height, components;
	bool is_float, is_alpha;
	TypeDesc typedesc;
	int basesize;
	char file_colorspace[IM_MAX_SPACE];

	/* load image from file through OIIO */
	if (imb_is_a_photoshop(filename) == 0) return (NULL);

	colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);

	in = ImageInput::create(filename);
	if (!in) {
		std::cerr << __func__ << ": ImageInput::create() failed:" << std::endl
		          << OpenImageIO::geterror() << std::endl;
		return NULL;
	}

	ImageSpec spec, config;
	config.attribute("oiio:UnassociatedAlpha", (int) 1);

	if (!in->open(filename, spec, config)) {
		std::cerr << __func__ << ": ImageInput::open() failed:" << std::endl
		          << in->geterror() << std::endl;
		delete in;
		return NULL;
	}

	string ics = spec.get_string_attribute("oiio:ColorSpace");
	BLI_strncpy(file_colorspace, ics.c_str(), IM_MAX_SPACE);

	/* only use colorspaces exis */
	if (colormanage_colorspace_get_named(file_colorspace))
		strcpy(colorspace, file_colorspace);
	else
		std::cerr << __func__ << ": The embed colorspace (\"" << file_colorspace
		          << "\") not supported in existent OCIO configuration file. Fallback "
		          << "to system default colorspace (\"" << colorspace << "\")." << std::endl;

	width = spec.width;
	height = spec.height;
	components = spec.nchannels;
	is_alpha = spec.alpha_channel != -1;
	basesize = spec.format.basesize();
	is_float = basesize > 1;

	/* we only handle certain number of components */
	if (!(components >= 1 && components <= 4)) {
		if (in) {
			in->close();
			delete in;
		}
		return NULL;
	}

	if (is_float)
		ibuf = imb_oiio_load_image_float(in, width, height, components, flags, is_alpha);
	else
		ibuf = imb_oiio_load_image(in, width, height, components, flags, is_alpha);

	if (in) {
		in->close();
		delete in;
	}

	if (!ibuf)
		return NULL;

	/* ImBuf always needs 4 channels */
	ibuf->ftype = IMB_FTYPE_PSD;
	ibuf->channels = 4;
	ibuf->planes = (3 + (is_alpha ? 1 : 0)) * 4 << basesize;

	try
	{
		return ibuf;
	}
	catch (const std::exception &exc)
	{
		std::cerr << exc.what() << std::endl;
		if (ibuf) IMB_freeImBuf(ibuf);

		return NULL;
	}
}
Example #13
0
bool
OiioTool::print_info (const std::string &filename, 
                      const print_info_options &opt,
                      long long &totalsize,
                      std::string &error)
{
    error.clear();
    ImageInput *input = ImageInput::create (filename.c_str(), "" /* searchpath */);
    if (! input) {
        error = geterror();
        if (error.empty())
            error = Strutil::format ("Could not open \"%s\"", filename.c_str());
        return false;
    }
    ImageSpec spec;
    if (! input->open (filename.c_str(), spec)) {
        error = input->geterror();
        if (error.empty())
            error = Strutil::format ("Could not open \"%s\"", filename.c_str());
        delete input;
        return false;
    }


    boost::regex field_re;
    if (! opt.metamatch.empty())
        field_re.assign (opt.metamatch,
                         boost::regex::extended | boost::regex_constants::icase);

    bool printed = false;
    int padlen = std::max (0, (int)opt.namefieldlength - (int)filename.length());
    std::string padding (padlen, ' ');

    // checking how many subimages and mipmap levels are stored in the file
    int num_of_subimages = 1;
    bool any_mipmapping = false;
    std::vector<int> num_of_miplevels;
    {
        int nmip = 1;
        while (input->seek_subimage (input->current_subimage(), nmip, spec)) {
            ++nmip;
            any_mipmapping = true;
        }
        num_of_miplevels.push_back (nmip);
    }
    while (input->seek_subimage (num_of_subimages, 0, spec)) {
        // maybe we should do this more gently?
        ++num_of_subimages;
        int nmip = 1;
        while (input->seek_subimage (input->current_subimage(), nmip, spec)) {
            ++nmip;
            any_mipmapping = true;
        }
        num_of_miplevels.push_back (nmip);
    }
    input->seek_subimage (0, 0, spec);  // re-seek to the first

    if (opt.metamatch.empty() ||
        boost::regex_search ("resolution, width, height, depth, channels", field_re)) {
        printf ("%s%s : %4d x %4d", filename.c_str(), padding.c_str(),
                spec.width, spec.height);
        if (spec.depth > 1)
            printf (" x %4d", spec.depth);
        printf (", %d channel, ", spec.nchannels);
        if (spec.channelformats.size()) {
            for (size_t c = 0;  c < spec.channelformats.size();  ++c)
                printf ("%s%s", c ? "/" : "",
                        spec.channelformats[c].c_str());
        } else {
            printf ("%s", spec.format.c_str());
        }
        if (spec.depth > 1)
            printf (" volume");
        printf (" %s", input->format_name());
        if (opt.sum) {
            imagesize_t imagebytes = spec.image_bytes (true);
            totalsize += imagebytes;
            printf (" (%.2f MB)", (float)imagebytes / (1024.0*1024.0));
        }
        // we print info about how many subimages are stored in file
        // only when we have more then one subimage
        if ( ! opt.verbose && num_of_subimages != 1)
            printf (" (%d subimages%s)", num_of_subimages,
                    any_mipmapping ? " +mipmap)" : "");
        if (! opt.verbose && num_of_subimages == 1 && any_mipmapping)
            printf (" (+mipmap)");
        printf ("\n");
        printed = true;
    }

    if (opt.verbose && num_of_subimages != 1) {
        // info about num of subimages and their resolutions
        printf ("    %d subimages: ", num_of_subimages);
        for (int i = 0; i < num_of_subimages; ++i) {
            input->seek_subimage (i, 0, spec);
            if (spec.depth > 1)
                printf ("%dx%dx%d ", spec.width, spec.height, spec.depth);
            else
                printf ("%dx%d ", spec.width, spec.height);
        }
        printf ("\n");
    }

    // if the '-a' flag is not set we print info
    // about first subimage only
    if ( ! opt.subimages)
        num_of_subimages = 1;
    for (int i = 0; i < num_of_subimages; ++i) {
        print_info_subimage (i, num_of_subimages, spec, input,
                             filename, opt, field_re);
    }

    input->close ();
    delete input;
    return true;
}
Example #14
0
bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
{
	if(img->filename == "")
		return false;

  fprintf(stderr, "image input disabled\n");
#if 0

	/* load image from file through OIIO */
	ImageInput *in = ImageInput::create(img->filename);

	if(!in)
		return false;

	ImageSpec spec;

	if(!in->open(img->filename, spec)) {
		delete in;
		return false;
	}

	/* we only handle certain number of components */
	int width = spec.width;
	int height = spec.height;
	int components = spec.nchannels;

	if(!(components == 1 || components == 3 || components == 4)) {
		in->close();
		delete in;
		return false;
	}

	/* read RGBA pixels */
	uchar *pixels = (uchar*)tex_img.resize(width, height);
	int scanlinesize = width*components*sizeof(uchar);

	in->read_image(TypeDesc::UINT8,
		(uchar*)pixels + (height-1)*scanlinesize,
		AutoStride,
		-scanlinesize,
		AutoStride);

	in->close();
	delete in;

	if(components == 3) {
		for(int i = width*height-1; i >= 0; i--) {
			pixels[i*4+3] = 255;
			pixels[i*4+2] = pixels[i*3+2];
			pixels[i*4+1] = pixels[i*3+1];
			pixels[i*4+0] = pixels[i*3+0];
		}
	}
	else if(components == 1) {
		for(int i = width*height-1; i >= 0; i--) {
			pixels[i*4+3] = 255;
			pixels[i*4+2] = pixels[i];
			pixels[i*4+1] = pixels[i];
			pixels[i*4+0] = pixels[i];
		}
	}

	return true;
#endif 
	return false;
}