00001
00002 #include "Util.h"
00003 #include "ViewportGL.h"
00004 #include "Message.h"
00005 #include <math.h>
00006
00007 namespace apig {
00008
00009
00010
00011
00012 template<class Color>
00013 Image1D<Color>::Image1D(int w, Color* inputData, WrapMode wrap, Color border) : AbstractImage1D(w), data(inputData), wrapMode(wrap), borderColor(border) {
00014 if (w <= 0) {
00015 w = 0;
00016 data = NULL;
00017 }
00018 else if (inputData == NULL) {
00019 data = new Color[w];
00020 if (data == NULL) {
00021 Message::error("l'allocation memoire pour l'image a echoué");
00022 w = 0;
00023 }
00024 }
00025 }
00026
00027 template<class Color>
00028 Image1D<Color>::Image1D(QImage image) : AbstractImage1D(0), data(NULL), wrapMode(CLAMP_TO_EDGE) {
00029 initialize(image);
00030 }
00031
00032 template<class Color>
00033 Image1D<Color>::Image1D(QString fileName) : AbstractImage1D(0), data(NULL), wrapMode(CLAMP_TO_EDGE) {
00034 QImage image(fileName);
00035 if (image.isNull())
00036 Message::error(QString("probleme lors du chargement du fichier '%1'").arg(fileName));
00037 else
00038 initialize(image);
00039 }
00040
00041 template<class Color>
00042 void Image1D<Color>::destroy() {
00043 if (data != NULL) delete[] data;
00044 data = NULL;
00045 w = 0;
00046 }
00047
00048 template<class Color>
00049 void Image1D<Color>::initialize(QImage image) {
00050 destroy();
00051 if (image.isNull())
00052 Message::error("l'image fournie ne contient pas de données");
00053 else {
00054 w = image.width();
00055 data = new Color[w];
00056 if (data == NULL) {
00057 Message::error("l'allocation memoire pour l'image a echoué");
00058 w = 0;
00059 }
00060 else
00061 for (int i=0; i<w; i++)
00062 texel(i) = Color(image.pixel(i, 0));
00063 }
00064 }
00065
00066 template<class Color>
00067 QImage Image1D<Color>::toQImage() const {
00068 QImage image(w, 1, QImage::Format_ARGB32);
00069 for (int i=0; i<w; i++)
00070 image.setPixel(i, 0, texel(i).toQRgb());
00071 return image;
00072 }
00073
00074 template<class Color>
00075 void Image1D<Color>::copy(const Image1D<Color> &image) {
00076 if (!image.loaded())
00077 Message::error("l'image fournie ne contient pas de données");
00078 else if (w < image.width())
00079 Message::error("l'image source est plus grande que l'image destination");
00080 else {
00081 for (int c=0; c<w; c++) data[c] = image.data[c];
00082 wrapMode = image.wrapMode;
00083 borderColor = image.borderColor;
00084 }
00085 }
00086
00087 template<class Color>
00088 Image1D<Color> Image1D<Color>::clone() const {
00089 if (data == NULL) return Image1D<Color>();
00090 Color *clonedData = new Color[w];
00091 if (clonedData == NULL) {
00092 Message::error("l'allocation memoire pour l'image a echoué");
00093 return Image1D<Color>();
00094 }
00095 for (int c=0; c<w; c++)
00096 clonedData[c] = data[c];
00097 return Image1D<Color>(w, clonedData, wrapMode, borderColor);
00098 }
00099
00100 template<class Color>
00101 void Image1D<Color>::setBorderColor(Color c) {
00102 borderColor = c;
00103 }
00104
00105 template<class Color>
00106 void Image1D<Color>::setWrapMode(WrapMode mode) {
00107 wrapMode = mode;
00108 }
00109
00110 template<class Color>
00111 void Image1D<Color>::setupBorder(WrapMode mode, Color c) {
00112 wrapMode = mode;
00113 borderColor = c;
00114 }
00115
00116 template<class Color>
00117 Color Image1D<Color>::sample(int i) const {
00118 switch (wrapMode) {
00119 case CLAMP_TO_BORDER : return contains(i) ? texel(i) : borderColor;
00120 case REPEAT : return texel(util::modulo(i, w));
00121 case MIRRORED_REPEAT : return texel(util::mirror(i, w));
00122 case CLAMP_TO_EDGE :
00123 default : return texel(util::clamp(i, 0, w-1));
00124 };
00125 }
00126
00127 template<class Color>
00128 Color Image1D<Color>::interp(float x) const {
00129 int i0 = (int)(floorf(x - 0.5));
00130 float a = x - 0.5 - i0;
00131 return (1 - a) * sample(i0) + a * sample(i0 + 1);
00132 }
00133
00134
00135
00136
00137 template<class Color>
00138 void Image1D<Color>::loadTexture1D(GLint texFormat, GLenum target) const {
00139 glTexImage1D(target, 0, texFormat, w, 0, Color::DATA_FORMAT, Color::DATA_TYPE, data);
00140 }
00141
00142 template<class Color>
00143 Image1D<Color> Image1D<Color>::readTexture(Texture *tex) {
00144 int w = tex->getWidth();
00145 Image1D<Color> res(w, NULL);
00146 if (w < 0)
00147 Message::error("dimensions de la texture non definies");
00148 else {
00149 tex->bind();
00150 glGetTexImage(GL_TEXTURE_1D, 0, Color::DATA_FORMAT, Color::DATA_TYPE, res.data);
00151 }
00152 return res;
00153 }
00154
00155 }
00156