diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-24 17:43:19 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-24 17:43:19 +0000 |
commit | 0292059f4a16434600564cfa3f0ad2309a508a54 (patch) | |
tree | d95953cd53011917c4df679b96aedca39401b54f /kernel/kls_bmp/fmt_codec_bmp.cpp | |
download | libksquirrel-0292059f4a16434600564cfa3f0ad2309a508a54.tar.gz libksquirrel-0292059f4a16434600564cfa3f0ad2309a508a54.zip |
Added libksquirrel for KDE3
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/libraries/libksquirrel@1095624 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kernel/kls_bmp/fmt_codec_bmp.cpp')
-rw-r--r-- | kernel/kls_bmp/fmt_codec_bmp.cpp | 445 |
1 files changed, 445 insertions, 0 deletions
diff --git a/kernel/kls_bmp/fmt_codec_bmp.cpp b/kernel/kls_bmp/fmt_codec_bmp.cpp new file mode 100644 index 0000000..c7be886 --- /dev/null +++ b/kernel/kls_bmp/fmt_codec_bmp.cpp @@ -0,0 +1,445 @@ +/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net) + + Copyright (c) 2004 Dmitry Baryshev <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later + version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + as32 with this library; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <iostream> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include "ksquirrel-libs/fmt_types.h" +#include "ksquirrel-libs/fileio.h" +#include "ksquirrel-libs/error.h" +#include "ksquirrel-libs/fmt_utils.h" + +#include "fmt_codec_bmp_defs.h" +#include "fmt_codec_bmp.h" + +#include "../xpm/codec_bmp.xpm" + +/* + * + * This library works with the graphics-file formats used by the Microsoft Windows(tm) + * operating system. + * + */ + +fmt_codec::fmt_codec() : fmt_codec_base() +{} + +fmt_codec::~fmt_codec() +{} + +void fmt_codec::options(codec_options *o) +{ + o->version = "1.1.2"; + o->name = "Windows Bitmap"; + o->filter = "*.bmp *.dib "; + o->config = ""; + o->mime = ""; + o->mimetype = "image/x-bmp"; + o->pixmap = codec_bmp; + o->readable = true; + o->canbemultiple = false; + o->writestatic = true; + o->writeanimated = false; + o->needtempfile = false; +} + +s32 fmt_codec::read_init(const std::string &file) +{ + frs.open(file.c_str(), ios::binary | ios::in); + + if(!frs.good()) + return SQE_R_NOFILE; + + pal_entr = 0; + currentImage = -1; + read_error = false; + + if(!frs.readK(&bfh, sizeof(BITMAPFILE_HEADER))) + return SQE_R_BADFILE; + + if(!frs.readK(&bih, sizeof(BITMAPINFO_HEADER))) + return SQE_R_BADFILE; + + if(bfh.Type != BMP_IDENTIFIER || bih.Size != 40) + return SQE_R_BADFILE; + + if(bih.Compression != BI_RGB) + return SQE_R_NOTSUPPORTED; + + finfo.animated = false; + + return SQE_OK; +} + +s32 fmt_codec::read_next() +{ + currentImage++; + + if(currentImage) + return SQE_NOTOK; + + fmt_image image; + + RGBA rgba; + s32 i, j, scanShouldBe; + + if(bih.BitCount < 16) + pal_entr = 1 << bih.BitCount; + else + pal_entr = 0; + + image.w = bih.Width; + image.h = bih.Height; + image.bpp = bih.BitCount; + scanShouldBe = bih.Width; + + switch(image.bpp) + { + case 1: + { + s32 _tmp = scanShouldBe; + scanShouldBe /= 8; + scanShouldBe = scanShouldBe + ((_tmp%8)?1:0); + } + break; + + case 4: scanShouldBe = ((image.w)%2)?((scanShouldBe+1)/2):(scanShouldBe/2); break; + case 8: break; + case 16: scanShouldBe *= 2; break; + case 24: scanShouldBe *= 3; break; + case 32: break; + + default: + return SQE_R_BADFILE; + } + + for(j = 0;j < 4;j++) + if((scanShouldBe+j)%4 == 0) + { + filler = j; + break; + } + + if(image.bpp < 16) + { + /* read palette */ + for(i = 0;i < pal_entr;i++) + { + if(!frs.readK(&rgba, sizeof(RGBA))) + return SQE_R_BADFILE; + + (pal)[i].r = rgba.b; + (pal)[i].g = rgba.g; + (pal)[i].b = rgba.r; + } + } + + /* fseek to image bits */ + frs.seekg(bfh.OffBits, ios::beg); + + image.needflip = true; + image.colorspace = (pal_entr ? "Color indexed":"RGB"); + image.compression = "-"; + + finfo.image.push_back(image); + + return SQE_OK; +} + +s32 fmt_codec::read_next_pass() +{ + return SQE_OK; +} + +s32 fmt_codec::read_scanline(RGBA *scan) +{ + u16 remain, scanShouldBe, j, counter = 0; + u8 bt, dummy; + fmt_image *im = image(currentImage); + fmt_utils::fillAlpha(scan, im->w); + + switch(im->bpp) + { + case 1: + { + u8 index; + remain=((im->w)<=8)?(0):((im->w)%8); + scanShouldBe = im->w; + + s32 _tmp = scanShouldBe; + scanShouldBe /= 8; + scanShouldBe = scanShouldBe + ((_tmp%8)?1:0); + + // @todo get rid of miltiple 'if' + for(j = 0;j < scanShouldBe;j++) + { + if(!frs.readK(&bt, 1)) + return SQE_R_BADFILE; + + if(j==scanShouldBe-1 && (remain-0)<=0 && remain)break; index = (bt & 128) >> 7; memcpy(scan+(counter++), (pal)+index, sizeof(RGB)); + if(j==scanShouldBe-1 && (remain-1)<=0 && remain)break; index = (bt & 64) >> 6; memcpy(scan+(counter++), (pal)+index, sizeof(RGB)); + if(j==scanShouldBe-1 && (remain-2)<=0 && remain)break; index = (bt & 32) >> 5; memcpy(scan+(counter++), (pal)+index, sizeof(RGB)); + if(j==scanShouldBe-1 && (remain-3)<=0 && remain)break; index = (bt & 16) >> 4; memcpy(scan+(counter++), (pal)+index, sizeof(RGB)); + if(j==scanShouldBe-1 && (remain-4)<=0 && remain)break; index = (bt & 8) >> 3; memcpy(scan+(counter++), (pal)+index, sizeof(RGB)); + if(j==scanShouldBe-1 && (remain-5)<=0 && remain)break; index = (bt & 4) >> 2; memcpy(scan+(counter++), (pal)+index, sizeof(RGB)); + if(j==scanShouldBe-1 && (remain-6)<=0 && remain)break; index = (bt & 2) >> 1; memcpy(scan+(counter++), (pal)+index, sizeof(RGB)); + if(j==scanShouldBe-1 && (remain-7)<=0 && remain)break; index = (bt & 1); memcpy(scan+(counter++), (pal)+index, sizeof(RGB)); + } + + for(j = 0;j < filler;j++) + { + if(!frs.readK(&dummy, 1)) + return SQE_R_BADFILE; + } + } + break; + + case 4: + { + u8 index; + remain = (im->w)%2; + + s32 ck = (im->w%2)?(im->w + 1):(im->w); + ck /= 2; + + for(j = 0;j < ck-1;j++) + { + if(!frs.readK(&bt, 1)) + return SQE_R_BADFILE; + + index = (bt & 0xf0) >> 4; + memcpy(scan+(counter++), (pal)+index, 3); + index = bt & 0xf; + memcpy(scan+(counter++), (pal)+index, 3); + } + + if(!frs.readK(&bt, 1)) + return SQE_R_BADFILE; + + index = (bt & 0xf0) >> 4; + memcpy(scan+(counter++), (pal)+index, 3); + + if(!remain) + { + index = bt & 0xf; + memcpy(scan+(counter++), (pal)+index, 3); + } + + for(j = 0;j < filler;j++) + { + if(!frs.readK(&dummy, 1)) + return SQE_R_BADFILE; + } + } + break; + + case 8: + { + for(j = 0;j < im->w;j++) + { + if(!frs.readK(&bt, 1)) + return SQE_R_BADFILE; + + memcpy(scan+(counter++), (pal)+bt, 3); + } + + for(j = 0;j < filler;j++) + { + if(!frs.readK(&dummy, 1)) + return SQE_R_BADFILE; + } + } + break; + + case 16: + { + u16 word; + + for(j = 0;j < im->w;j++) + { + if(!frs.readK(&word, 2)) + return SQE_R_BADFILE; + + scan[counter].b = (word&0x1f) << 3; + scan[counter].g = ((word&0x3e0) >> 5) << 3; + scan[counter++].r = ((word&0x7c00)>>10) << 3; + } + + for(j = 0;j < filler;j++) + { + if(!frs.readK(&dummy, 1)) + return SQE_R_BADFILE; + } + } + break; + + case 24: + { + RGB rgb; + + for(j = 0;j < im->w;j++) + { + if(!frs.readK(&rgb, sizeof(RGB))) + return SQE_R_BADFILE; + + scan[counter].r = rgb.b; + scan[counter].g = rgb.g; + scan[counter].b = rgb.r; + counter++; + } + + for(j = 0;j < filler;j++) + { + if(!frs.readK(&dummy, 1)) + return SQE_R_BADFILE; + } + } + break; + + case 32: + { + RGBA rgba; + + for(j = 0;j < im->w;j++) + { + if(!frs.readK(&rgba, sizeof(RGBA))) + return SQE_R_BADFILE; + + scan[j].r = rgba.b; + scan[j].g = rgba.g; + scan[j].b = rgba.r; + } + } + break; + + } + + return SQE_OK; +} + +void fmt_codec::read_close() +{ + frs.close(); + + finfo.meta.clear(); + finfo.image.clear(); +} + +void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt) +{ + opt->interlaced = false; + opt->compression_scheme = CompressionNo; + opt->compression_min = 0; + opt->compression_max = 0; + opt->compression_def = 0; + opt->passes = 1; + opt->needflip = true; + opt->palette_flags = 0 | fmt_image::pure32; +} + +s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt) +{ + if(!image.w || !image.h || file.empty()) + return SQE_W_WRONGPARAMS; + + writeimage = image; + writeopt = opt; + + fws.open(file.c_str(), ios::binary | ios::out); + + if(!fws.good()) + return SQE_W_NOFILE; + + m_FILLER = (image.w < 4) ? (4-image.w) : image.w%4; + + return SQE_OK; +} + +s32 fmt_codec::write_next() +{ + m_bfh.Type = BMP_IDENTIFIER; + m_bfh.Size = 0; + m_bfh.Reserved1 = 0; + m_bfh.OffBits = sizeof(BITMAPFILE_HEADER) + sizeof(BITMAPINFO_HEADER); + + m_bih.Size = 40; + m_bih.Width = writeimage.w; + m_bih.Height = writeimage.h; + m_bih.Planes = 1; + m_bih.BitCount = 24; + m_bih.Compression = BI_RGB; + m_bih.SizeImage = 0; + m_bih.XPelsPerMeter = 0; + m_bih.YPelsPerMeter = 0; + m_bih.ClrUsed = 0; + m_bih.ClrImportant = 0; + + if(!fws.writeK(&m_bfh, sizeof(BITMAPFILE_HEADER))) + return SQE_W_ERROR; + + if(!fws.writeK(&m_bih, sizeof(BITMAPINFO_HEADER))) + return SQE_W_ERROR; + + return SQE_OK; +} + +s32 fmt_codec::write_next_pass() +{ + return SQE_OK; +} + +s32 fmt_codec::write_scanline(RGBA *scan) +{ + s8 fillchar = '0'; + RGB rgb; + + for(s32 x = 0;x < writeimage.w;x++) + { + rgb.r = scan[x].b; + rgb.g = scan[x].g; + rgb.b = scan[x].r; + + if(!fws.writeK(&rgb, sizeof(RGB))) + return SQE_W_ERROR; + } + + if(m_FILLER) + { + for(s32 s = 0;s < m_FILLER;s++) + fws.writeK(&fillchar, sizeof(s8)); + } + + return SQE_OK; +} + +void fmt_codec::write_close() +{ + fws.close(); +} + +std::string fmt_codec::extension(const s32 /*bpp*/) +{ + return std::string("bmp"); +} + +#include "fmt_codec_cd_func.h" |