Esempio n. 1
0
/******************************************************************************
 Put one pixel (Pixel) into GIF file.
******************************************************************************/
int
EGifPutPixel(GifFileType *GifFile, GifPixelType Pixel)
{
    GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;

    if (!IS_WRITEABLE(Private)) {
        /* This file was NOT open for writing: */
        GifFile->Error = E_GIF_ERR_NOT_WRITEABLE;
        return GIF_ERROR;
    }

    if (Private->PixelCount == 0) {
        GifFile->Error = E_GIF_ERR_DATA_TOO_BIG;
        return GIF_ERROR;
    }
    --Private->PixelCount;

    /* Make sure the code is not out of bit range, as we might generate
     * wrong code (because of overflow when we combine them) in this case: */
    Pixel &= CodeMask[Private->BitsPerPixel];

    return EGifCompressLine(GifFile, &Pixel, 1);
}
Esempio n. 2
0
/******************************************************************************
 This routine should be called before any attempt to dump an image - any
 call to any of the pixel dump routines.
******************************************************************************/
int
EGifPutImageDesc(GifFileType *GifFile,
                 const int Left,
                 const int Top,
                 const int Width,
                 const int Height,
                 const bool Interlace,
                 const ColorMapObject *ColorMap)
{
    GifByteType Buf[3];
    GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;

    if (Private->FileState & FILE_STATE_IMAGE &&
        Private->PixelCount > 0xffff0000UL) {
        /* If already has active image descriptor - something is wrong! */
        GifFile->Error = E_GIF_ERR_HAS_IMAG_DSCR;
        return GIF_ERROR;
    }
    if (!IS_WRITEABLE(Private)) {
        /* This file was NOT open for writing: */
        GifFile->Error = E_GIF_ERR_NOT_WRITEABLE;
        return GIF_ERROR;
    }
    GifFile->Image.Left = Left;
    GifFile->Image.Top = Top;
    GifFile->Image.Width = Width;
    GifFile->Image.Height = Height;
    GifFile->Image.Interlace = Interlace;
    if (ColorMap) {
	if (GifFile->Image.ColorMap != NULL) {
	    GifFreeMapObject(GifFile->Image.ColorMap);
	    GifFile->Image.ColorMap = NULL;
	}
        GifFile->Image.ColorMap = GifMakeMapObject(ColorMap->ColorCount,
                                                ColorMap->Colors);
        if (GifFile->Image.ColorMap == NULL) {
            GifFile->Error = E_GIF_ERR_NOT_ENOUGH_MEM;
            return GIF_ERROR;
        }
    } else {
        GifFile->Image.ColorMap = NULL;
    }

    /* Put the image descriptor into the file: */
    Buf[0] = DESCRIPTOR_INTRODUCER;    /* Image separator character. */
    InternalWrite(GifFile, Buf, 1);
    (void)EGifPutWord(Left, GifFile);
    (void)EGifPutWord(Top, GifFile);
    (void)EGifPutWord(Width, GifFile);
    (void)EGifPutWord(Height, GifFile);
    Buf[0] = (ColorMap ? 0x80 : 0x00) |
       (Interlace ? 0x40 : 0x00) |
       (ColorMap ? ColorMap->BitsPerPixel - 1 : 0);
    InternalWrite(GifFile, Buf, 1);

    /* If we have Global color map - dump it also: */
    if (ColorMap != NULL) {
	int i;
        for (i = 0; i < ColorMap->ColorCount; i++) {
            /* Put the ColorMap out also: */
            Buf[0] = ColorMap->Colors[i].Red;
            Buf[1] = ColorMap->Colors[i].Green;
            Buf[2] = ColorMap->Colors[i].Blue;
            if (InternalWrite(GifFile, Buf, 3) != 3) {
                GifFile->Error = E_GIF_ERR_WRITE_FAILED;
                return GIF_ERROR;
            }
        }
    }
    if (GifFile->SColorMap == NULL && GifFile->Image.ColorMap == NULL) {
        GifFile->Error = E_GIF_ERR_NO_COLOR_MAP;
        return GIF_ERROR;
    }

    /* Mark this file as has screen descriptor: */
    Private->FileState |= FILE_STATE_IMAGE;
    Private->PixelCount = (long)Width *(long)Height;

    /* Reset compress algorithm parameters. */
    (void)EGifSetupCompress(GifFile);

    return GIF_OK;
}
Esempio n. 3
0
/******************************************************************************
 This routine should be called before any other EGif calls, immediately
 following the GIF file opening.
******************************************************************************/
int
EGifPutScreenDesc(GifFileType *GifFile,
                  const int Width,
                  const int Height,
                  const int ColorRes,
                  const int BackGround,
                  const ColorMapObject *ColorMap)
{
    GifByteType Buf[3];
    GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
    const char *write_version;

    if (Private->FileState & FILE_STATE_SCREEN) {
        /* If already has screen descriptor - something is wrong! */
        GifFile->Error = E_GIF_ERR_HAS_SCRN_DSCR;
        return GIF_ERROR;
    }
    if (!IS_WRITEABLE(Private)) {
        /* This file was NOT open for writing: */
        GifFile->Error = E_GIF_ERR_NOT_WRITEABLE;
        return GIF_ERROR;
    }

    write_version = EGifGetGifVersion(GifFile);

    /* First write the version prefix into the file. */
    if ((unsigned int)InternalWrite(GifFile, (unsigned char *)write_version,
              strlen(write_version)) != strlen(write_version)) {
        GifFile->Error = E_GIF_ERR_WRITE_FAILED;
        return GIF_ERROR;
    }

    GifFile->SWidth = Width;
    GifFile->SHeight = Height;
    GifFile->SColorResolution = ColorRes;
    GifFile->SBackGroundColor = BackGround;
    if (ColorMap) {
        GifFile->SColorMap = GifMakeMapObject(ColorMap->ColorCount,
                                           ColorMap->Colors);
        if (GifFile->SColorMap == NULL) {
            GifFile->Error = E_GIF_ERR_NOT_ENOUGH_MEM;
            return GIF_ERROR;
        }
    } else
        GifFile->SColorMap = NULL;

    /*
     * Put the logical screen descriptor into the file:
     */
    /* Logical Screen Descriptor: Dimensions */
    (void)EGifPutWord(Width, GifFile);
    (void)EGifPutWord(Height, GifFile);

    /* Logical Screen Descriptor: Packed Fields */
    /* Note: We have actual size of the color table default to the largest
     * possible size (7+1 == 8 bits) because the decoder can use it to decide
     * how to display the files.
     */
    Buf[0] = (ColorMap ? 0x80 : 0x00) | /* Yes/no global colormap */
             ((ColorRes - 1) << 4) | /* Bits allocated to each primary color */
        (ColorMap ? ColorMap->BitsPerPixel - 1 : 0x07 ); /* Actual size of the
                                                            color table. */
    if (ColorMap != NULL && ColorMap->SortFlag)
	Buf[0] |= 0x08;
    Buf[1] = BackGround;    /* Index into the ColorTable for background color */
    Buf[2] = GifFile->AspectByte;     /* Pixel Aspect Ratio */
    InternalWrite(GifFile, Buf, 3);

    /* If we have Global color map - dump it also: */
    if (ColorMap != NULL) {
	int i;
        for (i = 0; i < ColorMap->ColorCount; i++) {
            /* Put the ColorMap out also: */
            Buf[0] = ColorMap->Colors[i].Red;
            Buf[1] = ColorMap->Colors[i].Green;
            Buf[2] = ColorMap->Colors[i].Blue;
            if (InternalWrite(GifFile, Buf, 3) != 3) {
                GifFile->Error = E_GIF_ERR_WRITE_FAILED;
                return GIF_ERROR;
            }
        }
    }

    /* Mark this file as has screen descriptor, and no pixel written yet: */
    Private->FileState |= FILE_STATE_SCREEN;

    return GIF_OK;
}
Esempio n. 4
0
// make a node (regular files only at this time)
int fs_entry_mknod( struct fs_core* core, char const* path, mode_t mode, dev_t dev, uint64_t user, uint64_t vol ) {
    // only regular files at this time...
    if( ! ( S_ISREG( mode ) || S_ISFIFO( mode ) ) ) {
        return -ENOTSUP;
    }

    // revalidate this path
    int rc = fs_entry_revalidate_path( core, path );
    if( rc != 0 && rc != -ENOENT ) {
        // consistency cannot be guaranteed
        SG_error("fs_entry_revalidate_path(%s) rc = %d\n", path, rc );
        return rc;
    }

    int err = 0;

    // get the parent directory and lock it
    char* path_dirname = md_dirname( path, NULL );
    struct fs_entry* parent = fs_entry_resolve_path( core, path_dirname, user, vol, true, &err );
    free( path_dirname );

    if( !IS_DIR_READABLE( parent->mode, parent->owner, parent->volume, user, vol ) ) {
        // not searchable
        fs_entry_unlock( parent );
        return -EACCES;
    }

    if( !IS_WRITEABLE( parent->mode, parent->owner, parent->volume, user, vol ) ) {
        // not writeable
        fs_entry_unlock( parent );
        return -EACCES;
    }

    uint64_t parent_id = parent->file_id;
    char* parent_name = strdup( parent->name );

    char* path_basename = md_basename( path, NULL );

    // make sure it doesn't exist already (or isn't in the process of being deleted, since we might have to re-create it if deleting it fails)
    if( fs_entry_set_find_name( parent->children, path_basename ) != NULL ) {
        free( path_basename );
        fs_entry_unlock( parent );
        free( parent_name );
        return -EEXIST;
    }

    struct fs_entry* child = (struct fs_entry*)calloc( sizeof(struct fs_entry), 1 );

    struct timespec ts;
    clock_gettime( CLOCK_REALTIME, &ts );
    int mmode = 0;
    if (S_ISFIFO(mode)) {
        mmode = ( mode & 0777 ) | S_IFIFO;
        err = fs_entry_init_fifo( core, child, path_basename, 0, fs_entry_next_file_version(), user, core->gateway, vol, mmode, 0, ts.tv_sec, ts.tv_nsec, 0, 0 );
    }
    if (S_ISREG(mode)) {
        mmode = ( mode & 0777 );
        err = fs_entry_init_file( core, child, path_basename, 0, fs_entry_next_file_version(), user, core->gateway, vol, mmode, 0, ts.tv_sec, ts.tv_nsec, 0, 0 );
    }

    if( err == 0 ) {

        // mark it as created in this session
        child->created_in_session = true;

        // we're creating, so this manifest is initialized (to zero blocks)
        child->manifest->initialize_empty( child->version );

        fs_entry_wlock( child );

        // call the driver
        err = driver_create_file( core, core->closure, path, child );

        if( err != 0 ) {
            // undo
            SG_error("driver_create_file(%s) rc = %d\n", path, err );

            child->open_count = 0;

            fs_entry_unlock( child );
            fs_entry_destroy( child, false );
            free( child );
        }

        else {

            // attach the file
            fs_entry_attach_lowlevel( core, parent, child );

            struct md_entry data;
            fs_entry_to_md_entry( core, &data, child, parent_id, parent_name );

            // create the child on the MS, obtaining its file ID and write nonce
            err = ms_client_create( core->ms, &child->file_id, &child->write_nonce, &data );

            md_entry_free( &data );

            if( err != 0 ) {
                SG_error( "ms_client_create(%s) rc = %d\n", path, err );
                err = -EREMOTEIO;

                child->open_count = 0;
                fs_entry_unlock( child );
                fs_entry_detach_lowlevel( core, parent, child );
                free( child );
            }
            else {
                fs_entry_unlock( child );
            }
        }
    }

    fs_entry_unlock( parent );

    free( parent_name );
    free( path_basename );

    return err;
}
Esempio n. 5
0
// carry out the create locally.
// check permissions, initialize the child, and add it as a child of parent.
// return the initialized child (which will NOT be locked) via *ret_child
// return 0 on success
// return -EACCES on permission failure
// parent MUST be write locked
int fs_entry_do_create( struct fs_core* core, char const* path, struct fs_entry* parent, struct fs_entry** ret_child, uint64_t user, uint64_t vol, mode_t mode ) {

    int rc = 0;
    struct fs_entry* child = NULL;


    if( !IS_WRITEABLE(parent->mode, parent->owner, parent->volume, user, vol) ) {
        // can't create
        return -EACCES;
    }
    else {
        struct timespec ts;
        clock_gettime( CLOCK_REALTIME, &ts );

        // can create--initialize the child
        child = SG_CALLOC( struct fs_entry, 1 );

        char* path_basename = md_basename( path, NULL );

        rc = fs_entry_init_file( core, child, path_basename, 0, fs_entry_next_file_version(), user, core->gateway, vol, mode, 0, ts.tv_sec, ts.tv_nsec, 0, 0 );

        free( path_basename );

        if( rc != 0 ) {
            SG_error("fs_entry_init_file(%s) rc = %d\n", path, rc );

            fs_entry_destroy( child, false );
            free( child );

            return rc;
        }
        else {
            // mark it as created in this session
            child->created_in_session = true;

            // we're creating, so this manifest is initialized (to zero blocks)
            child->manifest->initialize_empty( child->version );

            // run the driver
            int driver_rc = driver_create_file( core, core->closure, path, child );
            if( driver_rc != 0 ) {
                SG_error("driver_create_file(%s) rc = %d\n", path, driver_rc );

                fs_entry_destroy( child, false );
                free( child );

                return driver_rc;
            }

            // insert it into the filesystem
            fs_entry_wlock( child );

            // open it
            child->open_count++;
            fs_entry_setup_working_data( core, child );

            fs_entry_attach_lowlevel( core, parent, child );

            fs_entry_unlock( child );

            *ret_child = child;
        }
    }

    return 0;
}