Simple Image Loading LibrarY  0.1.0
SILLYJPGImageLoader.cpp
1 /***********************************************************************
2  filename: SILLYJPGImageLoader.cpp
3  created: 11 Jun 2006
4  author: Olivier Delannoy
5 
6  purpose: Definition of JPGImageLoader methods
7 *************************************************************************/
8 /***************************************************************************
9  * Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining
12  * a copy of this software and associated documentation files (the
13  * "Software"), to deal in the Software without restriction, including
14  * without limitation the rights to use, copy, modify, merge, publish,
15  * distribute, sublicense, and/or sell copies of the Software, and to
16  * permit persons to whom the Software is furnished to do so, subject to
17  * the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be
20  * included in all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28  * OTHER DEALINGS IN THE SOFTWARE.
29  ***************************************************************************/
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33 
34 #include "loaders/SILLYJPGImageLoader.h"
35 
36 #ifndef SILLY_OPT_INLINE
37 #define inline
38 #include "loaders/SILLYJPGImageLoader.icpp"
39 #undef inline
40 #endif
41 #include "loaders/SILLYJPGImageContext.h"
42 
43 // Start section of namespace SILLY
44 namespace SILLY
45 {
46 JPGImageLoader::JPGImageLoader()
47  : ImageLoader("JPG Image Loader based on jpeg-6b")
48 {
49 }
50 
51 JPGImageLoader::~JPGImageLoader()
52 {
53 }
54 
55 
56 ImageContext* JPGImageLoader::loadHeader(PixelFormat& formatSource, DataSource* data)
57 {
59  jpg->d_source = data;
60 
61  if (! jpg)
62  return 0;
63  if (setjmp(jpg->setjmp_buffer))
64  {
65  delete jpg;
66  return 0;
67  }
68  jpeg_read_header(&(jpg->cinfo), TRUE);
69  if (! jpeg_start_decompress(&(jpg->cinfo)))
70  {
71  delete jpg;
72  return 0;
73  }
74 
75 
76  if (jpg->cinfo.output_components != 1 && jpg->cinfo.output_components != 3)
77  {
78  printf("JPG unsupported bpp: %d\n", jpg->cinfo.output_components );
79  jpeg_finish_decompress(& jpg->cinfo);
80  delete jpg;
81  return 0;
82  }
83  formatSource = PF_RGB; // It's not true but we handle both the same way
84  //printf("Image info: size: %dx%d - bpp: %d\n", jpg->cinfo.output_width, jpg->cinfo.output_height, jpg->cinfo.output_components);
85 
86  jpg->setImageSize();
87  return jpg;
88 }
89 
90 bool JPGImageLoader::loadImageData(PixelOrigin origin,
91  DataSource* data,
92  ImageContext* context)
93 {
94  JPGImageContext* jpg = static_cast<JPGImageContext*>(context);
95 
96  // Allocate a buffer
97  int row_stride = jpg->getWidth() * jpg->cinfo.output_components;
98  JSAMPARRAY buffer = (* jpg->cinfo.mem->alloc_sarray)(
99  (j_common_ptr)(& jpg->cinfo),
100  JPOOL_IMAGE,
101  row_stride,
102  1);
103  bool finished = true;
104  size_t height = jpg->getHeight();
105  size_t width = jpg->getWidth();
106 
107 
108  while(jpg->cinfo.output_scanline < height)
109  {
110  int num_rows = jpeg_read_scanlines(& jpg->cinfo, buffer, 1);
111  if (num_rows != 1)
112  {
113  jpeg_finish_decompress(& jpg->cinfo);
114  return false;
115  }
116  byte red;
117  byte green;
118  byte blue;
119  const byte alpha = 0xff;
120  byte* in = (byte*)(*buffer);
121  // Grayscale image
122  if (jpg->cinfo.output_components == 1)
123  {
124  for(size_t i = 0 ; i < width * num_rows ; ++i)
125  {
126  red = *in;
127  green = *in;
128  blue = *in;
129  jpg->setNextPixel(red, green, blue, alpha);
130  in += 1;
131  }
132  }
133  // RGB image
134  else
135  {
136  for(size_t i = 0 ; i < width * num_rows ; ++i)
137  {
138  red = *(in++);
139  green = *(in++);
140  blue = *(in++);
141  jpg->setNextPixel(red, green, blue, alpha);
142  }
143  }
144  }
145  jpeg_finish_decompress(& jpg->cinfo);
146 
147  if (origin == PO_BOTTOM_LEFT)
148  return jpg->flipVertically();
149  return true;
150 }
151 
152 
153 
154 
155 
156 
157 } // End section of namespace SILLY