Пример #1
0
static int
bitmap_decode(struct jpeg_decompress_struct *cinfo, Vbitmap *vbitmap,
              YmagineFormatOptions *options)
{
  int nlines = -1;

  cinfo->client_data = (void*) vbitmap;
  
  if (prepareDecompressor(cinfo, options) != YMAGINE_OK) {
    return nlines;
  }

  /* Intercept APP1 markers for PhotoSphere parsing */
  jpeg_set_marker_processor(cinfo, JPEG_APP0 + 1, APP1_handler);
  
  if (startDecompressor(cinfo, VbitmapColormode(vbitmap)) != YMAGINE_OK) {
    return nlines;
  }
  
  YmagineFormatOptions_invokeCallback(options, YMAGINE_IMAGEFORMAT_JPEG,
                                      cinfo->image_width, cinfo->image_height);

#if YMAGINE_DEBUG_JPEG
  ALOGD("bitmap_decode: in=%dx%d bm=%dx%d max=%dx%d",
        cinfo->image_width, cinfo->image_height,
        VbitmapWidth(vbitmap), VbitmapHeight(vbitmap),
        options->maxwidth, options->maxheight);
#endif
  
  nlines = decompress_jpeg(cinfo, NULL, JCOPYOPT_NONE,
                           vbitmap, options);
  
  return nlines;
}
Пример #2
0
/******************************************************************************
Description.: this is the main worker thread
              it loops forever, grabs a fresh frame, decompressed the JPEG
              and displays the decoded data using SDL
Input Value.:
Return Value:
******************************************************************************/
void *worker_thread(void *arg)
{
    int frame_size = 0, firstrun = 1;

    SDL_Surface *screen = NULL, *image = NULL;
    decompressed_image rgbimage;

    /* initialze the buffer for the decompressed image */
    rgbimage.buffersize = 0;
    rgbimage.buffer = NULL;

    /* initialze the SDL video subsystem */
    if(SDL_Init(SDL_INIT_VIDEO) < 0) {
        fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
        exit(EXIT_FAILURE);
    }

    /* just allocate a large buffer for the JPEGs */
    if((frame = malloc(4096 * 1024)) == NULL) {
        OPRINT("not enough memory for worker thread\n");
        exit(EXIT_FAILURE);
    }

    /* set cleanup handler to cleanup allocated ressources */
    pthread_cleanup_push(worker_cleanup, NULL);

    while(!pglobal->stop) {
        DBG("waiting for fresh frame\n");
        pthread_mutex_lock(&pglobal->in[input_number].db);
        pthread_cond_wait(&pglobal->in[plugin_number].db_update, &pglobal->in[plugin_number].db);

        /* read buffer */
        frame_size = pglobal->in[plugin_number].size;
        memcpy(frame, pglobal->in[plugin_number].buf, frame_size);

        pthread_mutex_unlock(&pglobal->in[plugin_number].db);

        /* decompress the JPEG and store results in memory */
        if(decompress_jpeg(frame, frame_size, &rgbimage)) {
            DBG("could not properly decompress JPEG data\n");
            continue;
        }

        if(firstrun) {
            /* create the primary surface (the visible window) */
            screen = SDL_SetVideoMode(rgbimage.width, rgbimage.height, 0, SDL_ANYFORMAT | SDL_HWSURFACE);
            SDL_WM_SetCaption("MJPG-Streamer Viewer", NULL);

            /* create a SDL surface to display the data */
            image = SDL_AllocSurface(SDL_SWSURFACE, rgbimage.width, rgbimage.height, 24,
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
                                     0x0000FF, 0x00FF00, 0xFF0000,
#else
                                     0xFF0000, 0x00FF00, 0x0000FF,
#endif
                                     0);

            /* copy the decoded data across */
            memcpy(image->pixels, rgbimage.buffer, rgbimage.width * rgbimage.height * 3);
            free(rgbimage.buffer);

            /* now, that we know the dimensions, we can directly copy to the right surface */
            rgbimage.buffer = image->pixels;
            rgbimage.buffersize = rgbimage.width * rgbimage.height * 3;

            firstrun = 0;
        }

        /* copy the image to the primary surface */
        SDL_BlitSurface(image, NULL, screen, NULL);

        /* redraw the whole surface */
        SDL_Flip(screen);
    }

    pthread_cleanup_pop(1);

    /* get rid of the image */
    SDL_FreeSurface(image);

    return NULL;
}
Пример #3
0
int
transcodeJPEG(Ychannel *channelin, Ychannel *channelout,
              YmagineFormatOptions *options)
{
  struct jpeg_decompress_struct cinfo;
  struct noop_error_mgr jerr;
  
  struct jpeg_compress_struct cinfoout;
  struct noop_error_mgr jerr2;
  int rc = YMAGINE_ERROR;
  int nlines = 0;
  int quality = YmagineFormatOptions_normalizeQuality(options);
  
  if (!YchannelReadable(channelin) || !YchannelWritable(channelout)) {
    return rc;
  }
  
  memset(&cinfo, 0, sizeof(struct jpeg_decompress_struct));
  cinfo.err = noop_jpeg_std_error(&jerr.pub);
  
  memset(&cinfoout, 0, sizeof(struct jpeg_compress_struct));
  cinfoout.err = noop_jpeg_std_error(&jerr2.pub);
  
  if (setjmp(jerr.setjmp_buffer)) {
    /* If we get here, the JPEG code has signaled an error in decoder */
    noop_append_jpeg_message((j_common_ptr) &cinfo);
  } else if (setjmp(jerr2.setjmp_buffer)) {
    /* If we get here, the JPEG code has signaled an error in encoder */
    noop_append_jpeg_message((j_common_ptr) &cinfoout);
  } else {
    jpeg_create_decompress(&cinfo);
    
    /* Equivalent to:
	   jpeg_CreateCompress(&cinfoout, JPEG_LIB_VERSION,
	   (size_t) sizeof(struct jpeg_compress_struct));
     */
    jpeg_create_compress(&cinfoout);

    if (ymaginejpeg_input(&cinfo, channelin) >= 0 &&
        ymaginejpeg_output(&cinfoout, channelout) >= 0) {
      if (prepareDecompressor(&cinfo, options) == YMAGINE_OK) {
        /* markers copy option (NONE, COMMENTS or ALL) */
        JCOPY_OPTION copyoption;
        int metamode = YMAGINE_METAMODE_DEFAULT;

        if (options != NULL) {
          metamode = options->metamode;
        }
        if (metamode == YMAGINE_METAMODE_NONE) {
          copyoption = JCOPYOPT_NONE;
        } else if (metamode == YMAGINE_METAMODE_COMMENTS) {
          copyoption = JCOPYOPT_COMMENTS;
        } else if (metamode == YMAGINE_METAMODE_ALL) {
          copyoption = JCOPYOPT_ALL;
        } else {
          /* Default to copy all markers */
          copyoption = JCOPYOPT_ALL;
        }

        /* Enable saving of extra markers that we want to copy */
        if (copyoption != JCOPYOPT_NONE) {
          jcopy_markers_setup(&cinfo, copyoption);
        }
        
        /* Force image to be decoded without colorspace conversion if possible */
        if (jpeg_read_header(&cinfo, TRUE) == JPEG_HEADER_OK) {
          YmagineFormatOptions_invokeCallback(options, YMAGINE_IMAGEFORMAT_JPEG,
                                              cinfo.image_width, cinfo.image_height);

          /* Other compression settings */
          int optimize = 0;
          int progressive = 0;
          int grayscale = 0;
          
          if (quality >= 90) {
            optimize = 1;
          }

          if (options != NULL && options->pixelshader != NULL) {
            /* If a shader is enabled, force RGBA mode */
            cinfo.out_color_space = JCS_EXT_RGBA;
            cinfoout.in_color_space = cinfo.out_color_space;
            cinfoout.input_components = 4;
          } else if (options != NULL && options->sharpen > 0.0f) {
            cinfo.out_color_space = JCS_RGB;
            cinfoout.in_color_space = cinfo.out_color_space;
            cinfoout.input_components = 3;
          } else {
            /* Otherwise sse same colorspace than input image (typically YCbCr) */
            cinfo.out_color_space = cinfo.jpeg_color_space;
            cinfoout.in_color_space = cinfo.out_color_space;
            cinfoout.input_components = JpegPixelSize(cinfoout.in_color_space);
          }

          jpeg_set_defaults(&cinfoout);
          cinfoout.optimize_coding = FALSE;
          
          jpeg_set_quality(&cinfoout, quality, FALSE);
          if (grayscale) {
            /* Force a monochrome JPEG file to be generated. */
            jpeg_set_colorspace(&cinfoout, JCS_GRAYSCALE);
          }
          if (optimize) {
            /* Enable entropy parm optimization. */
            cinfoout.optimize_coding = TRUE;
          }

          /* If non-zero, the input image is smoothed; the value should
             be 1 for minimal smoothing to 100 for maximum smoothing. */
          cinfoout.smoothing_factor = 0;

          if (progressive) {
            /* Select simple progressive mode. */
            jpeg_simple_progression(&cinfoout);
          }
          setCompressorOptions(&cinfoout, options);

          cinfo.client_data = (void*) NULL;
          cinfoout.client_data = (void*) NULL;

          nlines = decompress_jpeg(&cinfo, &cinfoout, copyoption, NULL, options);
          if (nlines > 0) {
            rc = YMAGINE_OK;
          }
        }
      }
    }
  }
  
  jpeg_destroy_compress(&cinfoout);
  jpeg_destroy_decompress(&cinfo);
  
  return rc;
}