//========================================================================
//
// DCTStream.cc
//
// This file is licensed under the GPLv2 or later
//
// Copyright 2005 Jeff Muizelaar <jeff@infidigm.net>
// Copyright 2005-2010, 2012 Albert Astals Cid <aacid@kde.org>
// Copyright 2009 Ryszard Trojnacki <rysiek@menel.com>
// Copyright 2010 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright 2011 Daiki Ueno <ueno@unixuser.org>
// Copyright 2011 Tomas Hoger <thoger@redhat.com>
// Copyright 2012, 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
//
//========================================================================

#include "DCTStream.h"

static void str_init_source(j_decompress_ptr cinfo)
{
}

static boolean str_fill_input_buffer(j_decompress_ptr cinfo)
{
  int c;
  struct str_src_mgr * src = (struct str_src_mgr *)cinfo->src;
  if (src->index == 0) {
    c = 0xFF;
    src->index++;
  }
  else if (src->index == 1) {
    c = 0xD8;
    src->index++;
  }
  else c = src->str->getChar();
  if (c != EOF)
  {
    src->buffer = c;
    src->pub.next_input_byte = &src->buffer;
    src->pub.bytes_in_buffer = 1;
    return TRUE;
  }
  else return FALSE;
}

static void str_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
{
  struct str_src_mgr * src = (struct str_src_mgr *)cinfo->src;
  if (num_bytes > 0) {
    while (num_bytes > (long) src->pub.bytes_in_buffer) {
      num_bytes -= (long) src->pub.bytes_in_buffer;
      str_fill_input_buffer(cinfo);
    }
    src->pub.next_input_byte += (size_t) num_bytes;
    src->pub.bytes_in_buffer -= (size_t) num_bytes;
  }
}

static void str_term_source(j_decompress_ptr cinfo)
{
}

DCTStream::DCTStream(Stream *strA, int colorXformA, Object *dict, int recursion) :
  FilterStream(strA) {
  colorXform = colorXformA;
  if (dict != NULL) {
    Object obj;

    dict->dictLookup("Width", &obj, recursion);
    err.width = (obj.isInt() && obj.getInt() <= JPEG_MAX_DIMENSION) ? obj.getInt() : 0;
    obj.free();
    dict->dictLookup("Height", &obj, recursion);
    err.height = (obj.isInt() && obj.getInt() <= JPEG_MAX_DIMENSION) ? obj.getInt() : 0;
    obj.free();
  } else
    err.height = err.width = 0;
  init();
}

DCTStream::~DCTStream() {
  jpeg_destroy_decompress(&cinfo);
  delete str;
}

static void exitErrorHandler(jpeg_common_struct *error) {
  j_decompress_ptr cinfo = (j_decompress_ptr)error;
  str_error_mgr * err = (struct str_error_mgr *)cinfo->err;
  if (cinfo->err->msg_code == JERR_IMAGE_TOO_BIG && err->width != 0 && err->height != 0) {
    cinfo->image_height = err->height;
    cinfo->image_width = err->width;
  } else {
    longjmp(err->setjmp_buffer, 1);
  }
}

void DCTStream::init()
{
  jpeg_std_error(&err.pub);
  err.pub.error_exit = &exitErrorHandler;
  src.pub.init_source = str_init_source;
  src.pub.fill_input_buffer = str_fill_input_buffer;
  src.pub.skip_input_data = str_skip_input_data;
  src.pub.resync_to_restart = jpeg_resync_to_restart;
  src.pub.term_source = str_term_source;
  src.pub.bytes_in_buffer = 0;
  src.pub.next_input_byte = NULL;
  src.str = str;
  src.index = 0;
  current = NULL;
  limit = NULL;
  
  cinfo.err = &err.pub;
  if (!setjmp(err.setjmp_buffer)) {
    jpeg_create_decompress(&cinfo);
    cinfo.src = (jpeg_source_mgr *)&src;
  }
  row_buffer = NULL;
}

void DCTStream::reset() {
  int row_stride;

  str->reset();

  if (row_buffer)
  {
    jpeg_destroy_decompress(&cinfo);
    init();
  }

  // JPEG data has to start with 0xFF 0xD8
  // but some pdf like the one on 
  // https://bugs.freedesktop.org/show_bug.cgi?id=3299
  // does have some garbage before that this seeks for
  // the start marker...
  bool startFound = false;
  int c = 0, c2 = 0;
  while (!startFound)
  {
    if (!c)
    {
      c = str->getChar();
      if (c == -1)
      {
        error(errSyntaxError, -1, "Could not find start of jpeg data");
        return;
      }
      if (c != 0xFF) c = 0;
    }
    else
    {
      c2 = str->getChar();
      if (c2 != 0xD8)
      {
        c = 0;
        c2 = 0;
      }
      else startFound = true;
    }
  }

  if (!setjmp(err.setjmp_buffer))
  {
    if (jpeg_read_header(&cinfo, TRUE) != JPEG_SUSPENDED)
    {
      // figure out color transform
      if (colorXform == -1 && !cinfo.saw_Adobe_marker) {
	if (cinfo.num_components == 3) {
	  if (cinfo.saw_JFIF_marker) {
	    colorXform = 1;
	  } else if (cinfo.cur_comp_info[0]->component_id == 82 &&
	      cinfo.cur_comp_info[1]->component_id == 71 &&
	      cinfo.cur_comp_info[2]->component_id == 66) { // ASCII "RGB"
	    colorXform = 0;
	  } else {
	    colorXform = 1;
	  }
	} else {
	  colorXform = 0;
	}
      } else if (cinfo.saw_Adobe_marker) {
	colorXform = cinfo.Adobe_transform;
      }

      switch (cinfo.num_components) {
      case 3:
	cinfo.jpeg_color_space = colorXform ? JCS_YCbCr : JCS_RGB;
	break;
      case 4:
	cinfo.jpeg_color_space = colorXform ? JCS_YCCK : JCS_CMYK;
	break;
      }

      jpeg_start_decompress(&cinfo);

      row_stride = cinfo.output_width * cinfo.output_components;
      row_buffer = cinfo.mem->alloc_sarray((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
    }
  }
}

// we can not go with inline since gcc
// refuses to inline because of setjmp
#define DO_GET_CHAR \
  if (current == limit) { \
    if (cinfo.output_scanline < cinfo.output_height) \
    { \
      if (!setjmp(err.setjmp_buffer)) \
      { \
        if (!jpeg_read_scanlines(&cinfo, row_buffer, 1)) c = EOF; \
        else { \
          current = &row_buffer[0][0]; \
          limit = &row_buffer[0][(cinfo.output_width - 1) * cinfo.output_components] + cinfo.output_components; \
          c = *current; \
          ++current; \
        } \
      } \
      else c = EOF; \
    } \
    else c = EOF; \
  } else { \
    c = *current; \
    ++current; \
  } \

int DCTStream::getChar() {
  int c;

  DO_GET_CHAR
  
  return c;
}

int DCTStream::getChars(int nChars, Guchar *buffer) {
  int c;
  for (int i = 0; i < nChars; ++i) {
    DO_GET_CHAR
    if (likely(c != EOF)) buffer[i] = c;
    else return i;
  }
  return nChars;
}

int DCTStream::lookChar() {
  if (unlikely(current == NULL)) {
    return EOF;
  }
  return *current;
}

GooString *DCTStream::getPSFilter(int psLevel, const char *indent) {
  GooString *s;

  if (psLevel < 2) {
    return NULL;
  }
  if (!(s = str->getPSFilter(psLevel, indent))) {
    return NULL;
  }
  s->append(indent)->append("<< >> /DCTDecode filter\n");
  return s;
}

GBool DCTStream::isBinary(GBool last) {
  return str->isBinary(gTrue);
}
