This is used to load BLP textures from World of Warcraft, but I'm pretty sure that they didn't modify their BLP format from Warcraft3 so this should work with it aswell.
void TextureManager::LoadBLP(GLuint id, Texture *tex){ // load BLP texture glBindTexture(GL_TEXTURE_2D, id); int offsets[16],sizes[16],w,h; GLint format; char attr[4]; MPQFile f(tex->name.c_str()); if (f.isEof()) { tex->id = 0; return; } f.seek(8); f.read(attr,4); f.read(&w,4); f.read(&h,4); f.read(offsets,4*16); f.read(sizes,4*16); tex->w = w; tex->h = h; bool hasmipmaps = attr[4]>0; int mipmax = hasmipmaps ? 16 : 1; if (attr[0] == 2) { // compressed unsigned char *ucbuf; if (!supportCompression) ucbuf = new unsigned char[w*h*4]; format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; int blocksize = 8; // guesswork here :( if (attr[1]==8) { format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; blocksize = 16; } else { if (!attr[3]) format = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; } tex->compressed = true; unsigned char *buf = new unsigned char[sizes[0]]; // do every mipmap level for (int i=0; i<mipmax; i++) { if (w==0) w = 1; if (h==0) h = 1; if (offsets && sizes) { f.seek(offsets); f.read(buf,sizes); int size = ((w+3)/4) * ((h+3)/4) * blocksize; if (supportCompression) { glCompressedTexImage2DARB(GL_TEXTURE_2D, i, format, w, h, 0, size, buf); } else { decompressDXTC(format, w, h, size, buf, ucbuf); glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ucbuf); } } else break; w >>= 1; h >>= 1; } delete[] buf; if (!supportCompression) delete[] ucbuf; } else if (attr[0]==1) { // uncompressed unsigned int pal[256]; f.read(pal,1024); unsigned char *buf = new unsigned char[sizes[0]]; unsigned int *buf2 = new unsigned int[w*h]; unsigned int *p; unsigned char *c, *a; int alphabits = attr[1]; bool hasalpha = alphabits!=0; tex->compressed = false; for (int i=0; i<mipmax; i++) { if (w==0) w = 1; if (h==0) h = 1; if (offsets && sizes) { f.seek(offsets); f.read(buf,sizes); int cnt = 0; p = buf2; c = buf; a = buf + w*h; for (int y=0; y<h; y++) { for (int x=0; x<w; x++) { unsigned int k = pal[*c++]; k = ((k&0x00FF0000)>>16) | ((k&0x0000FF00)) | ((k& 0x000000FF)<<16); int alpha; if (hasalpha) { if (alphabits == 8) { alpha = (*a++); } else if (alphabits == 1) { //alpha = (*a & (128 >> cnt++)) ? 0xff : 0; alpha = (*a & (1 << cnt++)) ? 0xff : 0; if (cnt == 8) { cnt = 0; a++; } } } else alpha = 0xff; k |= alpha << 24; *p++ = k; } } glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf2); } else break; w >>= 1; h >>= 1; } delete[] buf2; delete[] buf; } f.close(); if (hasmipmaps) { glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR); } else { glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); } // some models require texture wrapping though glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);}
Naturally you would have to change things like "MPQFile f(tex->name.c_str());" and actually open the BLP file instead, but this should give you the gist of it.
Also the BLP format is closer to TGA's, not JPEG's.